From b5b67a12b5f53e23f564ddd14cba280160a0af19 Mon Sep 17 00:00:00 2001 From: shiffman Date: Tue, 4 Sep 2012 01:45:28 +0000 Subject: [PATCH] removing Nature of Code bad filenames --- .../Connection.pde | 63 - .../Ex_10_5_LayeredNetworkAnimation.pde | 49 - .../Network.pde | 66 - .../Neuron.pde | 62 - .../sketch.properties | 1 - .../chp10_nn/LayeredNetworkViz/Connection.pde | 20 - .../LayeredNetworkViz/LayeredNetworkViz.pde | 14 - .../chp10_nn/LayeredNetworkViz/Network.pde | 45 - .../chp10_nn/LayeredNetworkViz/Neuron.pde | 29 - .../LayeredNetworkViz/sketch.properties | 1 - .../NOC_10_01_SimplePerceptron/Perceptron.pde | 59 - .../NOC_10_01_SimplePerceptron/Trainer.pde | 23 - .../_10_01_SimplePerceptron.pde | 89 - .../NOC_10_02_SeekingNeural/Perceptron.pde | 44 - .../NOC_10_02_SeekingNeural/Vehicle.pde | 102 - .../_10_02_SeekingNeural.pde | 62 - .../NOC_10_03_NetworkViz/Connection.pde | 29 - .../chp10_nn/NOC_10_03_NetworkViz/Network.pde | 37 - .../chp10_nn/NOC_10_03_NetworkViz/Neuron.pde | 36 - .../_10_03_NetworkViz.pde | 39 - .../NOC_10_03_NetworkViz/sketch.properties | 1 - .../NOC_10_04_NetworkAnimation/Connection.pde | 63 - .../NOC_10_04_NetworkAnimation/Network.pde | 62 - .../NOC_10_04_NetworkAnimation/Neuron.pde | 62 - .../_10_04_NetworkAnimation.pde | 50 - .../applet_js/NetworkAnimation.pde | 238 - .../applet_js/processing.js | 9994 ----------------- .../sketch.properties | 1 - .../Nature of Code/chp10_nn/xor/Landscape.pde | 73 - .../chp10_nn/xor/code/src/Connection.java | 47 - .../chp10_nn/xor/code/src/HiddenNeuron.java | 20 - .../chp10_nn/xor/code/src/InputNeuron.java | 23 - .../chp10_nn/xor/code/src/Network.java | 143 - .../chp10_nn/xor/code/src/Neuron.java | 81 - .../chp10_nn/xor/code/src/OutputNeuron.java | 7 - .../chp10_nn/xor/data/GillSans-16.vlw | Bin 28543 -> 0 bytes .../Books/Nature of Code/chp10_nn/xor/xor.pde | 114 - .../NOC_1_10_motion101_acceleration/Mover.pde | 55 - .../_1_10_motion101_acceleration.pde | 27 - .../Mover.pde | 55 - .../_1_11_motion101_acceleration_array.pde | 21 - .../_1_1_bouncingball_novectors.pde | 38 - .../_1_2_bouncingball_vectors.pde | 38 - .../_1_3_vector_subtraction.pde | 26 - .../_1_4_vector_multiplication.pde | 28 - .../_1_5_vector_magnitude.pde | 31 - .../_1_6_vector_normalize.pde | 38 - .../chp1_vectors/NOC_1_7_motion101/Mover.pde | 39 - .../NOC_1_7_motion101/_1_7_motion101.pde | 16 - .../NOC_1_8_motion101_acceleration/Mover.pde | 45 - .../_1_8_motion101_acceleration.pde | 17 - .../NOC_1_9_motion101_acceleration/Mover.pde | 49 - .../_1_9_motion101_acceleration.pde | 15 - .../NOC_02forces_attractrepel/Attractor.pde | 74 - .../NOC_02forces_attractrepel/Mover.pde | 69 - .../_02forces_attractrepel.pde | 52 - .../Attractor.pde | 39 - .../NOC_02forces_many_attraction_3D/Mover.pde | 51 - .../_02forces_many_attraction_3D.pde | 50 - .../sketch.properties | 1 - .../Mover.pde | 70 - .../_02forces_many_mutual_boundaries.pde | 44 - .../sketch.properties | 1 - .../_02forces_many_mutual_boundaries.pde | 115 - .../web-export/processing.js | 9994 ----------------- .../chp2_forces/NOC_2_1_forces/Mover.pde | 53 - .../NOC_2_1_forces/_2_1_forces.pde | 27 - .../chp2_forces/NOC_2_2_forces_many/Mover.pde | 53 - .../NOC_2_2_forces_many/_2_2_forces_many.pde | 36 - .../NOC_2_3_forces_many_realgravity/Mover.pde | 53 - .../_2_3_forces_many_realgravity.pde | 34 - .../NOC_2_4_forces_friction/Mover.pde | 53 - .../_2_4_forces_friction.pde | 42 - .../NOC_2_4_forces_nofriction/Mover.pde | 53 - .../_2_4_forces_nofriction.pde | 42 - .../NOC_2_5_fluidresistance/Liquid.pde | 62 - .../NOC_2_5_fluidresistance/Mover.pde | 64 - .../_2_5_fluidresistance.pde | 72 - .../NOC_2_5_fluidresistance/sketch.properties | 1 - .../web-export/_2_5_fluidresistance.pde | 199 - .../web-export/processing.js | 9994 ----------------- .../Liquid.pde | 62 - .../Mover.pde | 64 - .../_2_5_fluidresistance_sequence.pde | 74 - .../sketch.properties | 1 - .../web-export/_2_5_fluidresistance.pde | 199 - .../web-export/processing.js | 9994 ----------------- .../NOC_2_6_attraction/Attractor.pde | 77 - .../chp2_forces/NOC_2_6_attraction/Mover.pde | 51 - .../NOC_2_6_attraction/_2_6_attraction.pde | 36 - .../NOC_2_6_attraction/sketch.properties | 1 - .../web-export/_2_6_attraction.pde | 165 - .../web-export/processing.js | 9994 ----------------- .../NOC_2_7_attraction_many/Attractor.pde | 77 - .../NOC_2_7_attraction_many/Mover.pde | 33 - .../_2_7_attraction_many.pde | 46 - .../NOC_2_8_mutual_attraction/Mover.pde | 48 - .../_2_8_mutual_attraction.pde | 42 - .../sketch.properties | 1 - .../web-export/_2_8_mutual_attraction.pde | 91 - .../web-export/processing.js | 9994 ----------------- .../AdditiveWave/AdditiveWave.pde | 70 - .../AttractionArrayWithOscillation.pde | 46 - .../Attractor.pde | 81 - .../Crawler.pde | 56 - .../Oscillator.pde | 35 - .../Ex_3_01_exercise_baton.pde | 24 - .../Exercise_3_04_spiral/Ex_3_04_spiral.pde | 30 - .../Ex_3_05_asteroids.pde | 41 - .../Exercise_3_05_asteroids/Spaceship.pde | 97 - .../Exercise_3_10_OOPWave/Ex_3_10_OOPWave.pde | 31 - .../Exercise_3_10_OOPWave/Wave.pde | 45 - .../Ex_3_11_AdditiveWave.pde | 69 - .../_03spring_exercise_sine.pde | 21 - .../_3_01_angular_motion.pde | 30 - .../_3_01_angular_motion_trail.pde | 35 - .../Attractor.pde | 36 - .../Mover.pde | 49 - .../_3_02_forces_angular_mot_trails.pde | 44 - .../Attractor.pde | 36 - .../NOC_3_02_forces_angular_motion/Mover.pde | 49 - .../_3_02_forces_angular_motion.pde | 39 - .../NOC_3_03_pointing_velocity/Mover.pde | 65 - .../_3_03_pointing_velocity.pde | 17 - .../Mover.pde | 65 - .../_3_03_pointing_velocity_trail.pde | 25 - .../_3_04_PolarToCartesian.pde | 50 - .../_3_04_PolarToCartesian_trail.pde | 54 - .../_3_05_simple_harmonic_mot_trail.pde | 20 - .../_3_05_simple_harmonic_motion.pde | 18 - .../_3_06_simple_harmonic_motion.pde | 23 - .../Oscillator.pde | 33 - .../_3_07_oscillating_objects.pde | 33 - .../Oscillator.pde | 33 - .../_3_07_oscillating_objects_trail.pde | 36 - .../_3_08_static_wave_lines.pde | 19 - .../_3_09_exercise_additive_wave.pde | 70 - .../NOC_3_09_wave/_3_09_wave.pde | 28 - .../NOC_3_09_wave_a/_3_09_wave_a.pde | 28 - .../NOC_3_09_wave_b/_3_09_wave_b.pde | 28 - .../NOC_3_09_wave_c/_3_09_wave_c.pde | 28 - .../NOC_3_10_PendulumExample/Pendulum.pde | 95 - .../_3_10_PendulumExample.pde | 43 - .../Pendulum.pde | 61 - .../_3_10_PendulumExampleSimplified.pde | 34 - .../NOC_3_11_spring/Mover.pde | 78 - .../NOC_3_11_spring/Spring.pde | 75 - .../NOC_3_11_spring/_3_11_spring.pde | 61 - .../NOC_3_11_spring/sketch.properties | 2 - .../web-export/_3_11_spring.pde | 215 - .../NOC_3_11_spring/web-export/processing.js | 9994 ----------------- .../OOPWaveParticles/OOPWaveParticles.pde | 31 - .../OOPWaveParticles/Particle.pde | 20 - .../OOPWaveParticles/Wave.pde | 52 - .../CircleVsBlob/CircleVsBlob.pde | 28 - .../chp4_systems/CircleVsBlob/blob.tif | Bin 120768 -> 0 bytes .../chp4_systems/CircleVsBlob/circle.tif | Bin 120768 -> 0 bytes .../CircleVsBlob/data/texture.gif | Bin 1829 -> 0 bytes .../CircleVsBlob/data/texture.psd | Bin 26456 -> 0 bytes .../NOC_4_01_SingleParticle/Particle.pde | 49 - .../_4_01_SingleParticle.pde | 21 - .../Particle.pde | 49 - .../_4_01_SingleParticle_trail.pde | 23 - .../NOC_4_02_ArrayListParticles/Particle.pde | 49 - .../_4_02_ArrayListParticles.pde | 27 - .../NOC_4_03_ParticleSystemClass/Particle.pde | 49 - .../ParticleSystem.pde | 31 - .../_4_03_ParticleSystemClass.pde | 13 - .../NOC_4_04_SystemofSystems/Particle.pde | 49 - .../ParticleSystem.pde | 52 - .../_4_04_SystemofSystems.pde | 30 - .../NOC_4_04_SystemofSystems_b/Particle.pde | 49 - .../ParticleSystem.pde | 52 - .../_4_04_SystemofSystems_b.pde | 32 - .../NOC_4_04_SystemofSystems_c/Particle.pde | 49 - .../ParticleSystem.pde | 52 - .../_4_04_SystemofSystems_c.pde | 35 - .../Confetti.pde | 25 - .../Particle.pde | 50 - .../ParticleSystem.pde | 34 - ..._ParticleSystemInheritancePolymorphism.pde | 13 - .../Particle.pde | 57 - .../ParticleSystem.pde | 34 - .../_4_06_ParticleSystemForces.pde | 18 - .../Particle.pde | 57 - .../ParticleSystem.pde | 43 - .../Repeller.pde | 36 - .../_4_07_ParticleSystemForcesRepeller.pde | 23 - .../NOC_4_08_ParticleSystemSmoke/Particle.pde | 64 - .../ParticleSystem.pde | 62 - .../_4_08_ParticleSystemSmoke.pde | 54 - .../data/texture.psd | Bin 26456 -> 0 bytes .../sketch.properties | 1 - .../Particle.pde | 64 - .../ParticleSystem.pde | 62 - .../_4_08_ParticleSystemSmoke_b.pde | 54 - .../data/texture.psd | Bin 26456 -> 0 bytes .../sketch.properties | 2 - .../_4_08_ParticleSystemSmoke_b.pde | 179 - .../web-export/processing.js | 9994 ----------------- .../web-export/texture.psd | Bin 26456 -> 0 bytes .../NOC_4_09_AdditiveBlending/Particle.pde | 51 - .../ParticleSystem.pde | 53 - .../_4_09_AdditiveBlending.pde | 34 - .../data/texture.psd | Bin 26028 -> 0 bytes ..._04_6ParticleSystemInheritance_pushpop.pde | 13 - .../Particle.pde | 61 - .../ParticleChild.pde | 20 - .../ParticleSystem.pde | 34 - .../flight404_particles_1_simple/NOC_gl.pde | 11 - .../flight404_particles_1_simple/emitter.pde | 89 - .../flight404_particles_1_simple.pde | 160 - .../flight404_particles_1_simple/particle.pde | 208 - .../NOC_gl.pde | 49 - .../cursor.pde | 25 - .../emitter.pde | 182 - .../flight404_particles_2_GLtexture.pde | 210 - .../images.pde | 13 - .../nebula.pde | 56 - .../particle.pde | 171 - .../flight404_particles_2_GLtexture/pov.pde | 62 - .../sketch.properties | 1 - .../flight404_particles_2_simple/NOC_gl.pde | 31 - .../flight404_particles_2_simple/cursor.pde | 25 - .../flight404_particles_2_simple/emitter.pde | 149 - .../flight404_particles_2_simple.pde | 184 - .../flight404_particles_2_simple/images.pde | 13 - .../flight404_particles_2_simple/nebula.pde | 56 - .../flight404_particles_2_simple/particle.pde | 172 - .../flight404_particles_2_simple/pov.pde | 64 - .../chp4_systems/simpleInheritance/Circle.pde | 36 - .../chp4_systems/simpleInheritance/Shape.pde | 28 - .../chp4_systems/simpleInheritance/Square.pde | 25 - .../simpleInheritance/simpleInheritance.pde | 27 - .../simplePolymorphism/Circle.pde | 36 - .../chp4_systems/simplePolymorphism/Shape.pde | 28 - .../simplePolymorphism/Square.pde | 25 - .../simplePolymorphism/simplePolymorphism.pde | 32 - .../CollisionsEqualMass.pde | 33 - .../CollisionsEqualMass/Mover.pde | 99 - .../CollisionsEqualMass/drawVector.pde | 21 - .../box2d/BlobSkeleton/Blob.pde | 196 - .../box2d/BlobSkeleton/BlobSkeleton.pde | 112 - .../box2d/BlobSkeleton/Boundary.pde | 54 - .../box2d/BlobSkeleton/Box.pde | 86 - .../box2d/BlobSkeleton/Spring.pde | 76 - .../box2d/Blobby/Blob.pde | 117 - .../box2d/Blobby/Blobby.pde | 66 - .../box2d/Blobby/Boundary.pde | 54 - .../Boundary.pde | 56 - .../CollisionListeningDeletionExercise.pde | 121 - .../Particle.pde | 96 - .../box2d/CollisionsAndControl/Box.pde | 86 - .../CollisionsAndControl.pde | 153 - .../box2d/CollisionsAndControl/Particle.pde | 92 - .../box2d/CollisionsAndControl/Spring.pde | 82 - .../CollisionsAndControlInterface/Box.pde | 86 - .../CollisionsAndControlInterface.pde | 114 - .../ContactListener.pde | 57 - .../Particle.pde | 92 - .../CollisionsAndControlInterface/Spring.pde | 82 - .../Boundary.pde | 54 - .../Box.pde | 97 - .../Ex_5_10_ApplyForceAttractMouse.pde | 85 - .../Boundary.pde | 54 - .../Box.pde | 88 - .../Ex_5_10_ApplyForceSimpleWind.pde | 86 - .../Attractor.pde | 70 - .../Ex_5_10_AttractionApplyForce.pde | 60 - .../Mover.pde | 64 - .../Ex_5_3_NoiseChain.pde | 72 - .../Exercise_5_3_NoiseChain/Particle.pde | 90 - .../box2d/Exercise_5_3_NoiseChain/Surface.pde | 79 - .../Ex_5_3_SineChain.pde | 72 - .../box2d/Exercise_5_3_SineChain/Particle.pde | 90 - .../box2d/Exercise_5_3_SineChain/Surface.pde | 70 - .../box2d/Exercise_5_6_Bridge/Box.pde | 89 - .../box2d/Exercise_5_6_Bridge/Bridge.pde | 67 - .../Exercise_5_6_Bridge/Ex_5_6_Bridge.pde | 85 - .../box2d/Exercise_5_6_Bridge/Particle.pde | 79 - .../box2d/KinematicTest/Box.pde | 103 - .../box2d/KinematicTest/KinematicTest.pde | 144 - .../box2d/KinematicTest/Particle.pde | 93 - .../box2d/Liquidy/Boundary.pde | 62 - .../box2d/Liquidy/Liquidy.pde | 74 - .../box2d/Liquidy/Particle.pde | 99 - .../box2d/Liquidy/ParticleSystem.pde | 59 - .../box2d/MouseKinematic/Boundary.pde | 62 - .../box2d/MouseKinematic/Box.pde | 106 - .../box2d/MouseKinematic/MouseKinematic.pde | 78 - .../box2d/NOC_5_1_box2d_exercise/Box.pde | 23 - .../_5_1_box2d_exercise.pde | 24 - .../NOC_5_1_box2d_exercise_solved/Box.pde | 55 - .../_5_1_box2d_exercise_solved.pde | 37 - .../box2d/NOC_5_2_Boxes/Boundary.pde | 54 - .../box2d/NOC_5_2_Boxes/Box.pde | 88 - .../box2d/NOC_5_2_Boxes/_5_2_Boxes.pde | 74 - .../NOC_5_3_ChainShape_Simple/Particle.pde | 90 - .../NOC_5_3_ChainShape_Simple/Surface.pde | 53 - .../_5_3_ChainShape_Simple.pde | 72 - .../box2d/NOC_5_4_Polygons/Boundary.pde | 60 - .../box2d/NOC_5_4_Polygons/CustomShape.pde | 91 - .../box2d/NOC_5_4_Polygons/_5_4_Polygons.pde | 74 - .../box2d/NOC_5_5_MultiShapes/Boundary.pde | 62 - .../box2d/NOC_5_5_MultiShapes/Lollipop.pde | 89 - .../NOC_5_5_MultiShapes/_5_5_MultiShapes.pde | 74 - .../box2d/NOC_5_6_DistanceJoint/Boundary.pde | 54 - .../box2d/NOC_5_6_DistanceJoint/Pair.pde | 48 - .../box2d/NOC_5_6_DistanceJoint/Particle.pde | 77 - .../_5_6_DistanceJoint.pde | 81 - .../box2d/NOC_5_7_RevoluteJoint/Box.pde | 73 - .../box2d/NOC_5_7_RevoluteJoint/Particle.pde | 85 - .../box2d/NOC_5_7_RevoluteJoint/Windmill.pde | 62 - .../_5_7_RevoluteJoint.pde | 90 - .../box2d/NOC_5_8_MouseJoint/Boundary.pde | 63 - .../box2d/NOC_5_8_MouseJoint/Box.pde | 89 - .../box2d/NOC_5_8_MouseJoint/Spring.pde | 78 - .../NOC_5_8_MouseJoint/_5_8_MouseJoint.pde | 86 - .../NOC_5_9_CollisionListening/Boundary.pde | 56 - .../NOC_5_9_CollisionListening/Particle.pde | 91 - .../_5_9_CollisionListening.pde | 111 - .../box2d/VectorStuff/VectorStuff.pde | 57 - .../chp5_physicslibraries/readme.txt | 3 - .../Blanket.pde | 51 - .../Connection.pde | 11 - .../Ex_5_13_SoftBodySquareAdapted.pde | 63 - .../Particle.pde | 17 - .../Cluster.pde | 99 - .../Ex_5_15_ForceDirectedGraph.pde | 134 - .../Exercise_5_15_ForceDirectedGraph/Node.pde | 27 - .../NOC_5_10_SimpleSpring/Particle.pde | 18 - .../_5_10_SimpleSpring.pde | 70 - .../NOC_5_11_SoftStringPendulum/Chain.pde | 104 - .../NOC_5_11_SoftStringPendulum/Particle.pde | 20 - .../_5_11_SoftStringPendulum.pde | 70 - .../NOC_5_12_SimpleCluster/Cluster.pde | 64 - .../toxiclibs/NOC_5_12_SimpleCluster/Node.pde | 27 - .../_5_12_SimpleCluster.pde | 76 - .../NOC_5_13_AttractRepel/Attractor.pde | 17 - .../NOC_5_13_AttractRepel/Particle.pde | 20 - .../_5_13_AttractRepel.pde | 41 - .../chp6_agents/Cohesion/Cohesion.pde | 49 - .../chp6_agents/Cohesion/Vehicle.pde | 99 - .../CrowdPathFollowing/CrowdPathFollowing.pde | 76 - .../chp6_agents/CrowdPathFollowing/Path.pde | 50 - .../CrowdPathFollowing/Vehicle.pde | 239 - .../applet_js/CrowdPathFollowing.pde | 365 - .../applet_js/processing.js | 9994 ----------------- .../CrowdPathFollowing/sketch.properties | 1 - .../Exercise_6_04_Wander/Ex_6_04_Wander.pde | 30 - .../Exercise_6_04_Wander/Vehicle.pde | 123 - .../Ex_6_09_AngleBetween.pde | 54 - .../Ex_6_13_CrowdPathFollowing.pde | 77 - .../Exercise_6_13_CrowdPathFollowing/Path.pde | 50 - .../Vehicle.pde | 239 - .../applet_js/CrowdPathFollowing.pde | 365 - .../applet_js/processing.js | 9994 ----------------- .../sketch.properties | 1 - .../chp6_agents/NOC_6_01_Seek/Vehicle.pde | 74 - .../chp6_agents/NOC_6_01_Seek/_6_01_Seek.pde | 36 - .../NOC_6_01_Seek_trail/Vehicle.pde | 90 - .../NOC_6_01_Seek_trail/_6_01_Seek_trail.pde | 39 - .../chp6_agents/NOC_6_02_Arrive/Vehicle.pde | 80 - .../NOC_6_02_Arrive/_6_02_Arrive.pde | 35 - .../NOC_6_02_Arrive_trail/Vehicle.pde | 96 - .../_6_02_Arrive_trail.pde | 38 - .../NOC_6_03_StayWithinWalls/Vehicle.pde | 92 - .../_6_03_StayWithinWalls.pde | 37 - .../Vehicle.pde | 108 - .../_6_03_StayWithinWalls_trail.pde | 37 - .../NOC_6_04_Flow_Figures/FlowField.pde | 92 - .../NOC_6_04_Flow_Figures/Vehicle.pde | 85 - .../_6_04_Flow_Figures.pde | 34 - .../NOC_6_04_Flow_Figures/data/arrow.svg | 5149 --------- .../NOC_6_04_Flowfield/FlowField.pde | 77 - .../NOC_6_04_Flowfield/Vehicle.pde | 85 - .../NOC_6_04_Flowfield/_6_04_Flowfield.pde | 55 - .../NOC_6_04_Flowfield/sketch.properties | 0 .../web-export/_6_04_Flowfield.pde | 218 - .../web-export/processing.js | 9994 ----------------- .../NOC_6_05_PathFollowingSimple/Path.pde | 46 - .../NOC_6_05_PathFollowingSimple/Vehicle.pde | 161 - .../_6_05_PathFollowingSimple.pde | 52 - .../sketch.properties | 1 - .../web-export/_6_05_PathFollowingSimple.pde | 260 - .../web-export/processing.js | 9994 ----------------- .../NOC_6_06_PathFollowing/Path.pde | 48 - .../NOC_6_06_PathFollowing/Vehicle.pde | 190 - .../_6_06_PathFollowing.pde | 65 - .../NOC_6_07_Separation/Vehicle.pde | 99 - .../NOC_6_07_Separation/_6_07_Separation.pde | 45 - .../NOC_6_08_SeparationAndSeek/Vehicle.pde | 115 - .../_6_08_SeparationAndSeek.pde | 43 - .../sketch.properties | 1 - .../web-export/_6_08_SeparationAndSeek.pde | 159 - .../web-export/processing.js | 9994 ----------------- .../chp6_agents/NOC_6_09_Flocking/Boid.pde | 182 - .../chp6_agents/NOC_6_09_Flocking/Flock.pde | 25 - .../NOC_6_09_Flocking/_6_09_Flocking.pde | 38 - .../StayWithinCircle/StayWithinCircle.pde | 43 - .../chp6_agents/StayWithinCircle/Vehicle.pde | 95 - .../intersection/intersection/Thing.pde | 32 - .../intersection/intersection.pde | 106 - .../intersection/intersection_slow/Thing.pde | 32 - .../intersection_slow/intersection_slow.pde | 59 - .../chp6_agents/box2d/Flocking_box2d/Boid.pde | 255 - .../box2d/Flocking_box2d/Flock.pde | 25 - .../box2d/Flocking_box2d/Flocking_box2d.pde | 56 - .../chp6_agents/flocking_sliders/Boid.pde | 181 - .../chp6_agents/flocking_sliders/Flock.pde | 25 - .../flocking_sliders/flocking_sliders.pde | 60 - .../flocking_sliders/keyPressed.pde | 3 - .../flocking_sliders/scrollbar.pde | 133 - .../chp7_CA/Ex7_09_HexagonCells/Cell.pde | 38 - .../Ex7_09_HexagonCells.pde | 24 - .../chp7_CA/Ex7_09_HexagonCells/GOL.pde | 40 - .../CA.pde | 95 - .../Ex_7_01_WolframCA_randomizedrules.pde | 42 - .../Exercise_7_04_WolframCA_scrolling/CA.pde | 92 - .../Ex_7_04_WolframCA_scrolling.pde | 34 - .../CA.pde | 104 - .../Ex_7_04_WolframCA_scrolling_110.pde | 26 - .../CA.pde | 104 - .../Ex_7_04_WolframCA_scrolling_190.pde | 27 - .../CA.pde | 104 - .../Ex_7_04_WolframCA_scrolling_222.pde | 27 - .../CA.pde | 103 - .../Ex_7_04_WolframCA_scrolling_30.pde | 27 - .../Figure_7_17_cells/Figure_7_17_cells.pde | 28 - .../chp7_CA/Figure_7_17_cells/cells.tif | Bin 486768 -> 0 bytes .../chp7_CA/GameOfLifeWrapAround/GOL.pde | 73 - .../GameOfLifeWrapAround.pde | 31 - .../chp7_CA/HexagonCells/Cell.pde | 38 - .../chp7_CA/HexagonCells/GOL.pde | 40 - .../chp7_CA/HexagonCells/HexagonCells.pde | 24 - .../chp7_CA/NOC_7_01_WolframCA_figures/CA.pde | 92 - .../_7_01_WolframCA_figures.pde | 35 - .../chp7_CA/NOC_7_01_WolframCA_simple/CA.pde | 65 - .../_7_01_WolframCA_simple.pde | 21 - .../chp7_CA/NOC_7_02_GameOfLifeOOP/Cell.pde | 36 - .../chp7_CA/NOC_7_02_GameOfLifeOOP/GOL.pde | 69 - .../_7_02_GameOfLifeOOP.pde | 27 - .../chp7_CA/NOC_7_03_GameOfLifeSimple/GOL.pde | 73 - .../_7_03_GameOfLifeSimple.pde | 29 - .../CantorSetArrayList/CantorSetArrayList.pde | 47 - .../chp8_fractals/CantorSetArrayList/Line.pde | 23 - .../Ex_8_01_RecursionLines.pde | 35 - .../Ex_8_02_KochSnowFlake.pde | 54 - .../Exercise_8_02_KochSnowFlake/KochLine.pde | 71 - .../Exercise_8_06_Tree/Ex_8_06_Tree.pde | 56 - .../Exercise_8_07_Tree/Ex_8_07_Tree.pde | 51 - .../Figure_8_02_Mandelbrot.pde | 79 - .../Figure_8_14_Koch/Figure_8_14_Koch.pde | 65 - .../Figure_8_14_Koch/KochLine.pde | 71 - .../Figure_8_20_Tree/Figure_8_20_Tree.pde | 53 - .../Figure_8_CantorLine.pde | 20 - .../NOC_8_01_Recursion/_8_01_Recursion.pde | 26 - .../NOC_8_02_Recursion/_8_02_Recursion.pde | 27 - .../NOC_8_03_KochSimple/KochLine.pde | 71 - .../NOC_8_03_KochSimple/_8_03_KochSimple.pde | 50 - .../NOC_8_03_Recursion/_8_03_Recursion.pde | 28 - .../NOC_8_04_CantorSet/_8_04_CantorSet.pde | 38 - .../NOC_8_04_Tree/_8_04_Tree.pde | 52 - .../NOC_8_05_Koch/KochFractal.pde | 70 - .../chp8_fractals/NOC_8_05_Koch/KochLine.pde | 73 - .../NOC_8_05_Koch/_8_05_Koch.pde | 29 - .../NOC_8_05_Koch/sketch.properties | 2 - .../NOC_8_05_Koch/web-export/_8_05_Koch.pde | 174 - .../NOC_8_05_Koch/web-export/processing.js | 9994 ----------------- .../NOC_8_05_KochSimple/KochLine.pde | 71 - .../NOC_8_05_KochSimple/_8_05_KochSimple.pde | 50 - .../_8_05_TreeStochastic.pde | 63 - .../_8_06_SimpleLSystem.pde | 47 - .../NOC_8_06_Tree/_8_06_Tree.pde | 53 - .../_8_06_Tree_static.pde | 45 - .../_8_07_TreeStochastic.pde | 66 - .../_8_07_TreeStochastic_angleonly.pde | 59 - .../_8_08_SimpleLSystem.pde | 47 - .../NOC_8_09_LSystem/LSystem.pde | 67 - .../chp8_fractals/NOC_8_09_LSystem/Rule.pde | 26 - .../chp8_fractals/NOC_8_09_LSystem/Turtle.pde | 53 - .../NOC_8_09_LSystem/_8_09_LSystem.pde | 63 - .../NOC_8_09_LSystem/sketch.properties | 2 - .../web-export/_8_09_LSystem.pde | 210 - .../NOC_8_09_LSystem/web-export/processing.js | 9994 ----------------- .../chp8_fractals/Tree2/Branch.pde | 59 - .../chp8_fractals/Tree2/Tree2.pde | 47 - .../chp8_fractals/Tree3/Branch.pde | 66 - .../chp8_fractals/Tree3/Leaf.pde | 21 - .../chp8_fractals/Tree3/Tree3.pde | 58 - .../TreeStochasticNoise.pde | 71 - .../TreeStochasticNoise/sketch.properties | 1 - .../chp8_fractals/lsys/LSystem.pde | 67 - .../chp8_fractals/lsys/Rule.pde | 26 - .../chp8_fractals/lsys/Turtle.pde | 53 - .../chp8_fractals/lsys/lsys.pde | 56 - .../chp9_ga/EvolveFlowField/DNA.pde | 51 - .../EvolveFlowField/EvolveFlowField.pde | 100 - .../chp9_ga/EvolveFlowField/Obstacle.pde | 34 - .../chp9_ga/EvolveFlowField/Population.pde | 115 - .../chp9_ga/EvolveFlowField/Rocket.pde | 149 - .../GA_Shakespeare_fancyfitness/DNA.pde | 67 - .../GA_Shakespeare_fancyfitness.pde | 86 - .../Population.pde | 127 - .../chp9_ga/NOC_9_01_GA_Shakespeare/DNA.pde | 67 - .../NOC_9_01_GA_Shakespeare/Population.pde | 127 - .../_9_01_GA_Shakespeare.pde | 87 - .../NOC_9_01_GA_Shakespeare/sketch.properties | 2 - .../web-export/_9_01_GA_Shakespeare.pde | 282 - .../web-export/processing.js | 9994 ----------------- .../DNA.pde | 67 - .../_9_01_GA_Shakespeare_simplified.pde | 86 - .../sketch.properties | 2 - .../_9_01_GA_Shakespeare_simplified.pde | 154 - .../web-export/processing.js | 9994 ----------------- .../NOC_9_02_SmartRockets_superbasic/DNA.pde | 57 - .../Population.pde | 100 - .../Rocket.pde | 105 - .../_9_02_SmartRockets_superbasic.pde | 73 - .../chp9_ga/NOC_9_03_SmartRockets/DNA.pde | 65 - .../NOC_9_03_SmartRockets/Obstacle.pde | 37 - .../NOC_9_03_SmartRockets/Population.pde | 110 - .../chp9_ga/NOC_9_03_SmartRockets/Rocket.pde | 147 - .../_9_03_SmartRockets.pde | 93 - .../NOC_9_03_SmartRockets/sketch.properties | 1 - .../web-export/_9_03_SmartRockets.pde | 453 - .../web-export/processing.js | 9994 ----------------- .../Button.pde | 53 - .../DNA.pde | 46 - .../Face.pde | 101 - .../Population.pde | 99 - .../Rectangle.pde | 21 - .../_9_04_Faces_interactiveselection.pde | 46 - .../NOC_9_05_EvolutionEcosystem/Bloop.pde | 105 - .../NOC_9_05_EvolutionEcosystem/DNA.pde | 44 - .../NOC_9_05_EvolutionEcosystem/Food.pde | 41 - .../NOC_9_05_EvolutionEcosystem/World.pde | 56 - .../_9_05_EvolutionEcosystem.pde | 33 - .../sketch.properties | 1 - .../web-export/_9_05_EvolutionEcosystem.pde | 280 - .../web-export/processing.js | 9994 ----------------- .../chp9_ga/bruteforce/bruteforce.pde | 16 - .../Exc_I_10_NoiseLandscape.pde | 32 - .../Exc_I_10_NoiseLandscape/Landscape.pde | 65 - .../Exc_I_9_Noise3D/Exc_I_9_Noise3D.pde | 47 - .../Figure_I_2_BellCurve.pde | 38 - .../Figure_I_5_Noise1DGraph.pde | 27 - .../Figure_I_6_RandomGraph.pde | 22 - .../introduction/Gaussian2/Gaussian2.pde | 49 - .../MonteCarloDistribution/MonteCarlo.pde | 66 - .../MultipleProbability.pde | 39 - .../NOC_I_1_RandomWalkTraditional/Walker.pde | 38 - .../_I_1_RandomWalkTraditional.pde | 20 - .../_I_2_RandomDistribution.pde | 26 - .../NOC_I_3_RandomWalkTendsToRight/Walker.pde | 39 - .../_I_3_RandomWalkTendsToRight.pde | 20 - .../NOC_I_4_Gaussian/_I_4_Gaussian.pde | 32 - .../introduction/NOC_I_5_NoiseWalk/Walker.pde | 33 - .../NOC_I_5_NoiseWalk/_I_5_NoiseWalk.pde | 23 - .../introduction/Noise1D/Noise1D.pde | 31 - .../introduction/Noise2D/Noise2D.pde | 41 - .../NoiseDistribution/NoiseDistribution.pde | 33 - .../NoiseWalkAcceleration.pde | 24 - .../NoiseWalkAcceleration/Walker.pde | 65 - .../NoiseWalkVelocity/NoiseWalkVelocity.pde | 25 - .../introduction/NoiseWalkVelocity/Walker.pde | 60 - .../introduction/RandomWalk/RandomWalk.pde | 24 - .../introduction/RandomWalk/Walker.pde | 34 - .../RandomWalkLevy/RandomWalkLevy.pde | 20 - .../introduction/RandomWalkLevy/Walker.pde | 54 - .../RandomWalkNoise/RandomWalkNoise.pde | 20 - .../introduction/RandomWalkNoise/Walker.pde | 39 - .../RandomWalkPVector/RandomWalkPVector.pde | 24 - .../introduction/RandomWalkPVector/Walker.pde | 30 - .../RandomWalkTraditional2.pde | 20 - .../RandomWalkTraditional2/Walker.pde | 29 - .../RandomWalkTraditional3.pde | 20 - .../RandomWalkTraditional3/Walker.pde | 30 - .../RandomWalkTrail/RandomWalkTrail.pde | 24 - .../introduction/RandomWalkTrail/Walker.pde | 49 - .../SimpleProbablility/SimpleProbablility.pde | 34 - 581 files changed, 229203 deletions(-) delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/Connection.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/Ex_10_5_LayeredNetworkAnimation.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/Network.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/Neuron.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/Connection.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/LayeredNetworkViz.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/Network.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/Neuron.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/NOC_10_01_SimplePerceptron/Perceptron.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/NOC_10_01_SimplePerceptron/Trainer.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/NOC_10_01_SimplePerceptron/_10_01_SimplePerceptron.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/NOC_10_02_SeekingNeural/Perceptron.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/NOC_10_02_SeekingNeural/Vehicle.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/NOC_10_02_SeekingNeural/_10_02_SeekingNeural.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/Connection.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/Network.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/Neuron.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/_10_03_NetworkViz.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/Connection.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/Network.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/Neuron.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/_10_04_NetworkAnimation.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/applet_js/NetworkAnimation.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/applet_js/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/sketch.properties delete mode 100755 java/examples/Books/Nature of Code/chp10_nn/xor/Landscape.pde delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/xor/code/src/Connection.java delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/xor/code/src/HiddenNeuron.java delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/xor/code/src/InputNeuron.java delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/xor/code/src/Network.java delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/xor/code/src/Neuron.java delete mode 100644 java/examples/Books/Nature of Code/chp10_nn/xor/code/src/OutputNeuron.java delete mode 100755 java/examples/Books/Nature of Code/chp10_nn/xor/data/GillSans-16.vlw delete mode 100755 java/examples/Books/Nature of Code/chp10_nn/xor/xor.pde delete mode 100644 java/examples/Books/Nature of Code/chp1_vectors/NOC_1_10_motion101_acceleration/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp1_vectors/NOC_1_10_motion101_acceleration/_1_10_motion101_acceleration.pde delete mode 100644 java/examples/Books/Nature of Code/chp1_vectors/NOC_1_11_motion101_acceleration_array/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp1_vectors/NOC_1_11_motion101_acceleration_array/_1_11_motion101_acceleration_array.pde delete mode 100644 java/examples/Books/Nature of Code/chp1_vectors/NOC_1_1_bouncingball_novectors/_1_1_bouncingball_novectors.pde delete mode 100644 java/examples/Books/Nature of Code/chp1_vectors/NOC_1_2_bouncingball_vectors/_1_2_bouncingball_vectors.pde delete mode 100644 java/examples/Books/Nature of Code/chp1_vectors/NOC_1_3_vector_subtraction/_1_3_vector_subtraction.pde delete mode 100644 java/examples/Books/Nature of Code/chp1_vectors/NOC_1_4_vector_multiplication/_1_4_vector_multiplication.pde delete mode 100644 java/examples/Books/Nature of Code/chp1_vectors/NOC_1_5_vector_magnitude/_1_5_vector_magnitude.pde delete mode 100644 java/examples/Books/Nature of Code/chp1_vectors/NOC_1_6_vector_normalize/_1_6_vector_normalize.pde delete mode 100644 java/examples/Books/Nature of Code/chp1_vectors/NOC_1_7_motion101/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp1_vectors/NOC_1_7_motion101/_1_7_motion101.pde delete mode 100644 java/examples/Books/Nature of Code/chp1_vectors/NOC_1_8_motion101_acceleration/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp1_vectors/NOC_1_8_motion101_acceleration/_1_8_motion101_acceleration.pde delete mode 100644 java/examples/Books/Nature of Code/chp1_vectors/NOC_1_9_motion101_acceleration/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp1_vectors/NOC_1_9_motion101_acceleration/_1_9_motion101_acceleration.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_attractrepel/Attractor.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_attractrepel/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_attractrepel/_02forces_attractrepel.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_attraction_3D/Attractor.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_attraction_3D/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_attraction_3D/_02forces_many_attraction_3D.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_attraction_3D/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/_02forces_many_mutual_boundaries.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/web-export/_02forces_many_mutual_boundaries.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/web-export/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_1_forces/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_1_forces/_2_1_forces.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_2_forces_many/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_2_forces_many/_2_2_forces_many.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_3_forces_many_realgravity/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_3_forces_many_realgravity/_2_3_forces_many_realgravity.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_4_forces_friction/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_4_forces_friction/_2_4_forces_friction.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_4_forces_nofriction/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_4_forces_nofriction/_2_4_forces_nofriction.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/Liquid.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/_2_5_fluidresistance.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/web-export/_2_5_fluidresistance.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/web-export/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/Liquid.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/_2_5_fluidresistance_sequence.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/web-export/_2_5_fluidresistance.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/web-export/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/Attractor.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/_2_6_attraction.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/web-export/_2_6_attraction.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/web-export/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_7_attraction_many/Attractor.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_7_attraction_many/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_7_attraction_many/_2_7_attraction_many.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/_2_8_mutual_attraction.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/web-export/_2_8_mutual_attraction.pde delete mode 100644 java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/web-export/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/AdditiveWave/AdditiveWave.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/AttractionArrayWithOscillation/AttractionArrayWithOscillation.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/AttractionArrayWithOscillation/Attractor.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/AttractionArrayWithOscillation/Crawler.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/AttractionArrayWithOscillation/Oscillator.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_01_exercise_baton/Ex_3_01_exercise_baton.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_04_spiral/Ex_3_04_spiral.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_05_asteroids/Ex_3_05_asteroids.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_05_asteroids/Spaceship.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_10_OOPWave/Ex_3_10_OOPWave.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_10_OOPWave/Wave.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_11_AdditiveWave/Ex_3_11_AdditiveWave.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_03spring_exercise_sine/_03spring_exercise_sine.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_01_angular_motion/_3_01_angular_motion.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_01_angular_motion_trail/_3_01_angular_motion_trail.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_mot_trails/Attractor.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_mot_trails/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_mot_trails/_3_02_forces_angular_mot_trails.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_motion/Attractor.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_motion/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_motion/_3_02_forces_angular_motion.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_03_pointing_velocity/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_03_pointing_velocity/_3_03_pointing_velocity.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_03_pointing_velocity_trail/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_03_pointing_velocity_trail/_3_03_pointing_velocity_trail.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_04_PolarToCartesian/_3_04_PolarToCartesian.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_04_PolarToCartesian_trail/_3_04_PolarToCartesian_trail.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_05_simple_harmonic_mot_trail/_3_05_simple_harmonic_mot_trail.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_05_simple_harmonic_motion/_3_05_simple_harmonic_motion.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_06_simple_harmonic_motion/_3_06_simple_harmonic_motion.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_07_oscillating_objects/Oscillator.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_07_oscillating_objects/_3_07_oscillating_objects.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_07_oscillating_objects_trail/Oscillator.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_07_oscillating_objects_trail/_3_07_oscillating_objects_trail.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_08_static_wave_lines/_3_08_static_wave_lines.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_exercise_additive_wave/_3_09_exercise_additive_wave.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_wave/_3_09_wave.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_wave_a/_3_09_wave_a.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_wave_b/_3_09_wave_b.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_wave_c/_3_09_wave_c.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_10_PendulumExample/Pendulum.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_10_PendulumExample/_3_10_PendulumExample.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_10_PendulumExampleSimplified/Pendulum.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_10_PendulumExampleSimplified/_3_10_PendulumExampleSimplified.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/Spring.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/_3_11_spring.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/web-export/_3_11_spring.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/web-export/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/OOPWaveParticles/OOPWaveParticles.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/OOPWaveParticles/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp3_oscillation/OOPWaveParticles/Wave.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/CircleVsBlob/CircleVsBlob.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/CircleVsBlob/blob.tif delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/CircleVsBlob/circle.tif delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/CircleVsBlob/data/texture.gif delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/CircleVsBlob/data/texture.psd delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_01_SingleParticle/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_01_SingleParticle/_4_01_SingleParticle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_01_SingleParticle_trail/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_01_SingleParticle_trail/_4_01_SingleParticle_trail.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_02_ArrayListParticles/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_02_ArrayListParticles/_4_02_ArrayListParticles.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_03_ParticleSystemClass/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_03_ParticleSystemClass/ParticleSystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_03_ParticleSystemClass/_4_03_ParticleSystemClass.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems/ParticleSystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems/_4_04_SystemofSystems.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_b/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_b/ParticleSystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_b/_4_04_SystemofSystems_b.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_c/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_c/ParticleSystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_c/_4_04_SystemofSystems_c.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/Confetti.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/ParticleSystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/_4_05_ParticleSystemInheritancePolymorphism.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_06_ParticleSystemForces/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_06_ParticleSystemForces/ParticleSystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_06_ParticleSystemForces/_4_06_ParticleSystemForces.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_07_ParticleSystemForcesRepeller/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_07_ParticleSystemForcesRepeller/ParticleSystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_07_ParticleSystemForcesRepeller/Repeller.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_07_ParticleSystemForcesRepeller/_4_07_ParticleSystemForcesRepeller.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke/ParticleSystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke/_4_08_ParticleSystemSmoke.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke/data/texture.psd delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/ParticleSystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/_4_08_ParticleSystemSmoke_b.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/data/texture.psd delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/web-export/_4_08_ParticleSystemSmoke_b.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/web-export/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/web-export/texture.psd delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_09_AdditiveBlending/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_09_AdditiveBlending/ParticleSystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_09_AdditiveBlending/_4_09_AdditiveBlending.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/NOC_4_09_AdditiveBlending/data/texture.psd delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/ParticleSystemInheritance_pushpop/NOC_04_6ParticleSystemInheritance_pushpop.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/ParticleSystemInheritance_pushpop/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/ParticleSystemInheritance_pushpop/ParticleChild.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/ParticleSystemInheritance_pushpop/ParticleSystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_1_simple/NOC_gl.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_1_simple/emitter.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_1_simple/flight404_particles_1_simple.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_1_simple/particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/NOC_gl.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/cursor.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/emitter.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/flight404_particles_2_GLtexture.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/images.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/nebula.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/pov.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/NOC_gl.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/cursor.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/emitter.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/flight404_particles_2_simple.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/images.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/nebula.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/pov.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/simpleInheritance/Circle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/simpleInheritance/Shape.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/simpleInheritance/Square.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/simpleInheritance/simpleInheritance.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/simplePolymorphism/Circle.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/simplePolymorphism/Shape.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/simplePolymorphism/Square.pde delete mode 100644 java/examples/Books/Nature of Code/chp4_systems/simplePolymorphism/simplePolymorphism.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/CollisionsEqualMass/CollisionsEqualMass.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/CollisionsEqualMass/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/CollisionsEqualMass/drawVector.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/Blob.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/BlobSkeleton.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/Boundary.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/Box.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/Spring.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Blobby/Blob.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Blobby/Blobby.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Blobby/Boundary.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionListeningDeletionExercise/Boundary.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionListeningDeletionExercise/CollisionListeningDeletionExercise.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionListeningDeletionExercise/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControl/Box.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControl/CollisionsAndControl.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControl/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControl/Spring.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/Box.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/CollisionsAndControlInterface.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/ContactListener.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/Spring.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceAttractMouse/Boundary.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceAttractMouse/Box.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceAttractMouse/Ex_5_10_ApplyForceAttractMouse.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceSimpleWind/Boundary.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceSimpleWind/Box.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceSimpleWind/Ex_5_10_ApplyForceSimpleWind.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_AttractionApplyForce/Attractor.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_AttractionApplyForce/Ex_5_10_AttractionApplyForce.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_AttractionApplyForce/Mover.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_NoiseChain/Ex_5_3_NoiseChain.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_NoiseChain/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_NoiseChain/Surface.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_SineChain/Ex_5_3_SineChain.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_SineChain/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_SineChain/Surface.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_6_Bridge/Box.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_6_Bridge/Bridge.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_6_Bridge/Ex_5_6_Bridge.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_6_Bridge/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/KinematicTest/Box.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/KinematicTest/KinematicTest.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/KinematicTest/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Liquidy/Boundary.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Liquidy/Liquidy.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Liquidy/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Liquidy/ParticleSystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/MouseKinematic/Boundary.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/MouseKinematic/Box.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/MouseKinematic/MouseKinematic.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_1_box2d_exercise/Box.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_1_box2d_exercise/_5_1_box2d_exercise.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_1_box2d_exercise_solved/Box.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_1_box2d_exercise_solved/_5_1_box2d_exercise_solved.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_2_Boxes/Boundary.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_2_Boxes/Box.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_2_Boxes/_5_2_Boxes.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_3_ChainShape_Simple/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_3_ChainShape_Simple/Surface.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_3_ChainShape_Simple/_5_3_ChainShape_Simple.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_4_Polygons/Boundary.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_4_Polygons/CustomShape.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_4_Polygons/_5_4_Polygons.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_5_MultiShapes/Boundary.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_5_MultiShapes/Lollipop.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_5_MultiShapes/_5_5_MultiShapes.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_6_DistanceJoint/Boundary.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_6_DistanceJoint/Pair.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_6_DistanceJoint/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_6_DistanceJoint/_5_6_DistanceJoint.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_7_RevoluteJoint/Box.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_7_RevoluteJoint/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_7_RevoluteJoint/Windmill.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_7_RevoluteJoint/_5_7_RevoluteJoint.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_8_MouseJoint/Boundary.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_8_MouseJoint/Box.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_8_MouseJoint/Spring.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_8_MouseJoint/_5_8_MouseJoint.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_9_CollisionListening/Boundary.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_9_CollisionListening/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_9_CollisionListening/_5_9_CollisionListening.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/VectorStuff/VectorStuff.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/readme.txt delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_13_SoftBodySquareAdapted/Blanket.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_13_SoftBodySquareAdapted/Connection.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_13_SoftBodySquareAdapted/Ex_5_13_SoftBodySquareAdapted.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_13_SoftBodySquareAdapted/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_15_ForceDirectedGraph/Cluster.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_15_ForceDirectedGraph/Ex_5_15_ForceDirectedGraph.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_15_ForceDirectedGraph/Node.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_10_SimpleSpring/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_10_SimpleSpring/_5_10_SimpleSpring.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_11_SoftStringPendulum/Chain.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_11_SoftStringPendulum/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_11_SoftStringPendulum/_5_11_SoftStringPendulum.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_12_SimpleCluster/Cluster.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_12_SimpleCluster/Node.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_12_SimpleCluster/_5_12_SimpleCluster.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_13_AttractRepel/Attractor.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_13_AttractRepel/Particle.pde delete mode 100644 java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_13_AttractRepel/_5_13_AttractRepel.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/Cohesion/Cohesion.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/Cohesion/Vehicle.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/CrowdPathFollowing.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/Path.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/Vehicle.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/applet_js/CrowdPathFollowing.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/applet_js/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/Exercise_6_04_Wander/Ex_6_04_Wander.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/Exercise_6_04_Wander/Vehicle.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/Exercise_6_09_AngleBetween/Ex_6_09_AngleBetween.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/Ex_6_13_CrowdPathFollowing.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/Path.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/Vehicle.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/applet_js/CrowdPathFollowing.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/applet_js/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_01_Seek/Vehicle.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_01_Seek/_6_01_Seek.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_01_Seek_trail/Vehicle.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_01_Seek_trail/_6_01_Seek_trail.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_02_Arrive/Vehicle.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_02_Arrive/_6_02_Arrive.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_02_Arrive_trail/Vehicle.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_02_Arrive_trail/_6_02_Arrive_trail.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_03_StayWithinWalls/Vehicle.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_03_StayWithinWalls/_6_03_StayWithinWalls.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_03_StayWithinWalls_trail/Vehicle.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_03_StayWithinWalls_trail/_6_03_StayWithinWalls_trail.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flow_Figures/FlowField.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flow_Figures/Vehicle.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flow_Figures/_6_04_Flow_Figures.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flow_Figures/data/arrow.svg delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/FlowField.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/Vehicle.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/_6_04_Flowfield.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/web-export/_6_04_Flowfield.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/web-export/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/Path.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/Vehicle.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/_6_05_PathFollowingSimple.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/web-export/_6_05_PathFollowingSimple.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/web-export/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_06_PathFollowing/Path.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_06_PathFollowing/Vehicle.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_06_PathFollowing/_6_06_PathFollowing.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_07_Separation/Vehicle.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_07_Separation/_6_07_Separation.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/Vehicle.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/_6_08_SeparationAndSeek.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/web-export/_6_08_SeparationAndSeek.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/web-export/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_09_Flocking/Boid.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_09_Flocking/Flock.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/NOC_6_09_Flocking/_6_09_Flocking.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/StayWithinCircle/StayWithinCircle.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/StayWithinCircle/Vehicle.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/binlatticespatialsubdivision/intersection/intersection/Thing.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/binlatticespatialsubdivision/intersection/intersection/intersection.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/binlatticespatialsubdivision/intersection/intersection_slow/Thing.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/binlatticespatialsubdivision/intersection/intersection_slow/intersection_slow.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/box2d/Flocking_box2d/Boid.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/box2d/Flocking_box2d/Flock.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/box2d/Flocking_box2d/Flocking_box2d.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/Boid.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/Flock.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/flocking_sliders.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/keyPressed.pde delete mode 100644 java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/scrollbar.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/Ex7_09_HexagonCells/Cell.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/Ex7_09_HexagonCells/Ex7_09_HexagonCells.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/Ex7_09_HexagonCells/GOL.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/Exercise_7_01_WolframCA_randomizedrules/CA.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/Exercise_7_01_WolframCA_randomizedrules/Ex_7_01_WolframCA_randomizedrules.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling/CA.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling/Ex_7_04_WolframCA_scrolling.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_110/CA.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_110/Ex_7_04_WolframCA_scrolling_110.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_190/CA.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_190/Ex_7_04_WolframCA_scrolling_190.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_222/CA.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_222/Ex_7_04_WolframCA_scrolling_222.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_30/CA.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_30/Ex_7_04_WolframCA_scrolling_30.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/Figure_7_17_cells/Figure_7_17_cells.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/Figure_7_17_cells/cells.tif delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/GameOfLifeWrapAround/GOL.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/GameOfLifeWrapAround/GameOfLifeWrapAround.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/HexagonCells/Cell.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/HexagonCells/GOL.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/HexagonCells/HexagonCells.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/NOC_7_01_WolframCA_figures/CA.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/NOC_7_01_WolframCA_figures/_7_01_WolframCA_figures.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/NOC_7_01_WolframCA_simple/CA.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/NOC_7_01_WolframCA_simple/_7_01_WolframCA_simple.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/NOC_7_02_GameOfLifeOOP/Cell.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/NOC_7_02_GameOfLifeOOP/GOL.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/NOC_7_02_GameOfLifeOOP/_7_02_GameOfLifeOOP.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/NOC_7_03_GameOfLifeSimple/GOL.pde delete mode 100644 java/examples/Books/Nature of Code/chp7_CA/NOC_7_03_GameOfLifeSimple/_7_03_GameOfLifeSimple.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/CantorSetArrayList/CantorSetArrayList.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/CantorSetArrayList/Line.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_01_RecursionLines/Ex_8_01_RecursionLines.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_02_KochSnowFlake/Ex_8_02_KochSnowFlake.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_02_KochSnowFlake/KochLine.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_06_Tree/Ex_8_06_Tree.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_07_Tree/Ex_8_07_Tree.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/Figure_8_02_Mandelbrot/Figure_8_02_Mandelbrot.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/Figure_8_14_Koch/Figure_8_14_Koch.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/Figure_8_14_Koch/KochLine.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/Figure_8_20_Tree/Figure_8_20_Tree.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/Figure_8_CantorLine/Figure_8_CantorLine.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_01_Recursion/_8_01_Recursion.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_02_Recursion/_8_02_Recursion.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_03_KochSimple/KochLine.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_03_KochSimple/_8_03_KochSimple.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_03_Recursion/_8_03_Recursion.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_04_CantorSet/_8_04_CantorSet.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_04_Tree/_8_04_Tree.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/KochFractal.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/KochLine.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/_8_05_Koch.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/web-export/_8_05_Koch.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/web-export/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_KochSimple/KochLine.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_KochSimple/_8_05_KochSimple.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_TreeStochastic/_8_05_TreeStochastic.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_06_SimpleLSystem/_8_06_SimpleLSystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_06_Tree/_8_06_Tree.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_06_Tree_static/_8_06_Tree_static.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_07_TreeStochastic/_8_07_TreeStochastic.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_07_TreeStochastic_angleonly/_8_07_TreeStochastic_angleonly.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_08_SimpleLSystem/_8_08_SimpleLSystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/LSystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/Rule.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/Turtle.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/_8_09_LSystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/web-export/_8_09_LSystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/web-export/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/Tree2/Branch.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/Tree2/Tree2.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/Tree3/Branch.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/Tree3/Leaf.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/Tree3/Tree3.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/TreeStochasticNoise/TreeStochasticNoise.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/TreeStochasticNoise/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/lsys/LSystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/lsys/Rule.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/lsys/Turtle.pde delete mode 100644 java/examples/Books/Nature of Code/chp8_fractals/lsys/lsys.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/DNA.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/EvolveFlowField.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/Obstacle.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/Population.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/Rocket.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/GA_Shakespeare_fancyfitness/DNA.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/GA_Shakespeare_fancyfitness/GA_Shakespeare_fancyfitness.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/GA_Shakespeare_fancyfitness/Population.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/DNA.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/Population.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/_9_01_GA_Shakespeare.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/web-export/_9_01_GA_Shakespeare.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/web-export/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare_simplified/DNA.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare_simplified/_9_01_GA_Shakespeare_simplified.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare_simplified/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare_simplified/web-export/_9_01_GA_Shakespeare_simplified.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare_simplified/web-export/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_02_SmartRockets_superbasic/DNA.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_02_SmartRockets_superbasic/Population.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_02_SmartRockets_superbasic/Rocket.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_02_SmartRockets_superbasic/_9_02_SmartRockets_superbasic.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/DNA.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/Obstacle.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/Population.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/Rocket.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/_9_03_SmartRockets.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/web-export/_9_03_SmartRockets.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/web-export/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/Button.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/DNA.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/Face.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/Population.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/Rectangle.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/_9_04_Faces_interactiveselection.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/Bloop.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/DNA.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/Food.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/World.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/_9_05_EvolutionEcosystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/sketch.properties delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/web-export/_9_05_EvolutionEcosystem.pde delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/web-export/processing.js delete mode 100644 java/examples/Books/Nature of Code/chp9_ga/bruteforce/bruteforce.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/Exc_I_10_NoiseLandscape/Exc_I_10_NoiseLandscape.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/Exc_I_10_NoiseLandscape/Landscape.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/Exc_I_9_Noise3D/Exc_I_9_Noise3D.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/Figure_I_2_BellCurve/Figure_I_2_BellCurve.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/Figure_I_5_Noise1DGraph/Figure_I_5_Noise1DGraph.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/Figure_I_6_RandomGraph/Figure_I_6_RandomGraph.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/Gaussian2/Gaussian2.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/MonteCarloDistribution/MonteCarlo.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/MultipleProbability/MultipleProbability.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/NOC_I_1_RandomWalkTraditional/Walker.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/NOC_I_1_RandomWalkTraditional/_I_1_RandomWalkTraditional.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/NOC_I_2_RandomDistribution/_I_2_RandomDistribution.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/NOC_I_3_RandomWalkTendsToRight/Walker.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/NOC_I_3_RandomWalkTendsToRight/_I_3_RandomWalkTendsToRight.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/NOC_I_4_Gaussian/_I_4_Gaussian.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/NOC_I_5_NoiseWalk/Walker.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/NOC_I_5_NoiseWalk/_I_5_NoiseWalk.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/Noise1D/Noise1D.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/Noise2D/Noise2D.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/NoiseDistribution/NoiseDistribution.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/NoiseWalkAcceleration/NoiseWalkAcceleration.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/NoiseWalkAcceleration/Walker.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/NoiseWalkVelocity/NoiseWalkVelocity.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/NoiseWalkVelocity/Walker.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/RandomWalk/RandomWalk.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/RandomWalk/Walker.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/RandomWalkLevy/RandomWalkLevy.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/RandomWalkLevy/Walker.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/RandomWalkNoise/RandomWalkNoise.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/RandomWalkNoise/Walker.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/RandomWalkPVector/RandomWalkPVector.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/RandomWalkPVector/Walker.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/RandomWalkTraditional2/RandomWalkTraditional2.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/RandomWalkTraditional2/Walker.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/RandomWalkTraditional3/RandomWalkTraditional3.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/RandomWalkTraditional3/Walker.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/RandomWalkTrail/RandomWalkTrail.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/RandomWalkTrail/Walker.pde delete mode 100644 java/examples/Books/Nature of Code/introduction/SimpleProbablility/SimpleProbablility.pde diff --git a/java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/Connection.pde b/java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/Connection.pde deleted file mode 100644 index 8d6ec8907..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/Connection.pde +++ /dev/null @@ -1,63 +0,0 @@ -// An animated drawing of a Neural Network -// Daniel Shiffman -// Nature of Code - -class Connection { - // Connection is from Neuron A to B - Neuron a; - Neuron b; - - // Connection has a weight - float weight; - - // Variables to track the animation - boolean sending = false; - PVector sender; - - // Need to store the output for when its time to pass along - float output = 0; - - Connection(Neuron from, Neuron to, float w) { - weight = w; - a = from; - b = to; - } - - - // The Connection is active - void feedforward(float val) { - output = val*weight; // Compute output - sender = a.location.get(); // Start animation at Neuron A - sending = true; // Turn on sending - } - - // Update traveling sender - void update() { - if (sending) { - // Use a simple interpolation - sender.x = lerp(sender.x, b.location.x, 0.1); - sender.y = lerp(sender.y, b.location.y, 0.1); - float d = PVector.dist(sender, b.location); - // If we've reached the end - if (d < 1) { - // Pass along the output! - b.feedforward(output); - sending = false; - } - } - } - - // Draw line and traveling circle - void display() { - stroke(0); - strokeWeight(1+weight*4); - line(a.location.x, a.location.y, b.location.x, b.location.y); - - if (sending) { - fill(0); - strokeWeight(1); - ellipse(sender.x, sender.y, 16, 16); - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/Ex_10_5_LayeredNetworkAnimation.pde b/java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/Ex_10_5_LayeredNetworkAnimation.pde deleted file mode 100644 index 951bf44c0..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/Ex_10_5_LayeredNetworkAnimation.pde +++ /dev/null @@ -1,49 +0,0 @@ -// An animated drawing of a Neural Network -// Daniel Shiffman -// Nature of Code - -Network network; - -void setup() { - size(750,200); - smooth(); - - // Create the Network object - network = new Network(width/2, height/2); - - int layers = 3; - int inputs = 2; - - Neuron output = new Neuron(250, 0); - for (int i = 0; i < layers; i++) { - for (int j = 0; j < inputs; j++) { - float x = map(i, 0, layers, -300, 300); - float y = map(j, 0, inputs-1, -75, 75); - Neuron n = new Neuron(x, y); - if (i > 0) { - for (int k = 0; k < inputs; k++) { - Neuron prev = network.neurons.get(network.neurons.size()-inputs+k-j); - network.connect(prev, n, random(1)); - } - } - if (i == layers-1) { - network.connect(n, output, random(1)); - } - network.addNeuron(n); - } - } - network.addNeuron(output); -} - -void draw() { - background(255); - // Update and display the Network - network.update(); - network.display(); - - // Every 30 frames feed in an input - if (frameCount % 30 == 0) { - network.feedforward(random(1),random(1)); - } -} - diff --git a/java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/Network.pde b/java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/Network.pde deleted file mode 100644 index 045808741..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/Network.pde +++ /dev/null @@ -1,66 +0,0 @@ -// An animated drawing of a Neural Network -// Daniel Shiffman -// Nature of Code - -class Network { - - // The Network has a list of neurons - ArrayList neurons; - - // The Network now keeps a duplicate list of all Connection objects. - // This makes it easier to draw everything in this class - ArrayList connections; - PVector location; - - Network(float x, float y) { - location = new PVector(x, y); - neurons = new ArrayList(); - connections = new ArrayList(); - } - - // We can add a Neuron - void addNeuron(Neuron n) { - neurons.add(n); - } - - // We can connection two Neurons - void connect(Neuron a, Neuron b, float weight) { - Connection c = new Connection(a, b, weight); - a.addConnection(c); - // Also add the Connection here - connections.add(c); - } - - // Sending an input to the first Neuron - // We should do something better to track multiple inputs - void feedforward(float input1, float input2) { - Neuron n1 = neurons.get(0); - n1.feedforward(input1); - - Neuron n2 = neurons.get(1); - n2.feedforward(input2); - - } - - // Update the animation - void update() { - for (Connection c : connections) { - c.update(); - } - } - - // Draw everything - void display() { - pushMatrix(); - translate(location.x, location.y); - for (Neuron n : neurons) { - n.display(); - } - - for (Connection c : connections) { - c.display(); - } - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/Neuron.pde b/java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/Neuron.pde deleted file mode 100644 index 372ba3fa7..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/Neuron.pde +++ /dev/null @@ -1,62 +0,0 @@ -// An animated drawing of a Neural Network -// Daniel Shiffman -// Nature of Code - -class Neuron { - // Neuron has a location - PVector location; - - // Neuron has a list of connections - ArrayList connections; - - // We now track the inputs and sum them - float sum = 0; - - // The Neuron's size can be animated - float r = 32; - - Neuron(float x, float y) { - location = new PVector(x, y); - connections = new ArrayList(); - } - - // Add a Connection - void addConnection(Connection c) { - connections.add(c); - } - - // Receive an input - void feedforward(float input) { - // Accumulate it - sum += input; - // Activate it? - if (sum > 1) { - fire(); - sum = 0; // Reset the sum to 0 if it fires - } - } - - // The Neuron fires - void fire() { - r = 64; // It suddenly is bigger - - // We send the output through all connections - for (Connection c : connections) { - c.feedforward(sum); - } - } - - // Draw it as a circle - void display() { - stroke(0); - strokeWeight(1); - // Brightness is mapped to sum - float b = map(sum,0,1,255,0); - fill(b); - ellipse(location.x, location.y, r, r); - - // Size shrinks down back to original dimensions - r = lerp(r,32,0.1); - } -} - diff --git a/java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/sketch.properties b/java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/sketch.properties deleted file mode 100644 index 28faa5897..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/Exercise_10_5_LayeredNetworkAnimation/sketch.properties +++ /dev/null @@ -1 +0,0 @@ -mode=Standard diff --git a/java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/Connection.pde b/java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/Connection.pde deleted file mode 100644 index e0a563df8..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/Connection.pde +++ /dev/null @@ -1,20 +0,0 @@ -class Connection { - float weight; - Neuron a; - Neuron b; - - Connection(Neuron from, Neuron to,float w) { - weight = w; - a = from; - b = to; - } - - void display() { - stroke(0); - strokeWeight(weight*4); - line(a.location.x, a.location.y, b.location.x, b.location.y); - } -} - - - diff --git a/java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/LayeredNetworkViz.pde b/java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/LayeredNetworkViz.pde deleted file mode 100644 index 0e5597662..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/LayeredNetworkViz.pde +++ /dev/null @@ -1,14 +0,0 @@ - -Network network; - -void setup() { - size(640, 360); - smooth(); - network = new Network(4,3,1); -} - -void draw() { - background(255); - network.display(); -} - diff --git a/java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/Network.pde b/java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/Network.pde deleted file mode 100644 index 2a5515ea2..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/Network.pde +++ /dev/null @@ -1,45 +0,0 @@ - - -class Network { - ArrayList neurons; - PVector location; - Network(int layers, int inputs, int outputs) { - location = new PVector(width/2, height/2); - - neurons = new ArrayList(); - - Neuron output = new Neuron(250, 0); - for (int i = 0; i < layers; i++) { - for (int j = 0; j < inputs; j++) { - float x = map(i, 0, layers, -200, 200); - float y = map(j, 0, inputs-1, -100, 100); - println(j + " " + y); - Neuron n = new Neuron(x, y); - - if (i > 0) { - for (int k = 0; k < inputs; k++) { - Neuron prev = neurons.get(neurons.size()-inputs+k-j); - prev.connect(n); - } - } - - if (i == layers-1) { - n.connect(output); - } - neurons.add(n); - } - } - neurons.add(output); - } - - - void display() { - pushMatrix(); - translate(location.x, location.y); - for (Neuron n : neurons) { - n.display(); - } - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/Neuron.pde b/java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/Neuron.pde deleted file mode 100644 index b99256c82..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/Neuron.pde +++ /dev/null @@ -1,29 +0,0 @@ - - -class Neuron { - PVector location; - - ArrayList connections; - - Neuron(float x, float y) { - location = new PVector(x, y); - connections = new ArrayList(); - } - - void connect(Neuron n) { - Connection c = new Connection(this, n, random(1)); - connections.add(c); - } - - void display() { - stroke(0); - strokeWeight(1); - fill(0); - ellipse(location.x, location.y, 16, 16); - - for (Connection c : connections) { - c.display(); - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/sketch.properties b/java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/sketch.properties deleted file mode 100644 index 28faa5897..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/LayeredNetworkViz/sketch.properties +++ /dev/null @@ -1 +0,0 @@ -mode=Standard diff --git a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_01_SimplePerceptron/Perceptron.pde b/java/examples/Books/Nature of Code/chp10_nn/NOC_10_01_SimplePerceptron/Perceptron.pde deleted file mode 100644 index f49e0343b..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_01_SimplePerceptron/Perceptron.pde +++ /dev/null @@ -1,59 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/teaching/nature -// Simple Perceptron Example -// See: http://en.wikipedia.org/wiki/Perceptron - -// Perceptron Class - -class Perceptron { - float[] weights; // Array of weights for inputs - float c; // learning constant - - // Perceptron is created with n weights and learning constant - Perceptron(int n, float c_) { - weights = new float[n]; - // Start with random weights - for (int i = 0; i < weights.length; i++) { - weights[i] = random(-1,1); - } - c = c_; - } - - // Function to train the Perceptron - // Weights are adjusted based on "desired" answer - void train(float[] inputs, int desired) { - // Guess the result - int guess = feedforward(inputs); - // Compute the factor for changing the weight based on the error - // Error = desired output - guessed output - // Note this can only be 0, -2, or 2 - // Multiply by learning constant - float error = desired - guess; - // Adjust weights based on weightChange * input - for (int i = 0; i < weights.length; i++) { - weights[i] += c * error * inputs[i]; - } - } - - // Guess -1 or 1 based on input values - int feedforward(float[] inputs) { - // Sum all values - float sum = 0; - for (int i = 0; i < weights.length; i++) { - sum += inputs[i]*weights[i]; - } - // Result is sign of the sum, -1 or 1 - return activate(sum); - } - - int activate(float sum) { - if (sum > 0) return 1; - else return -1; - } - - // Return weights - float[] getWeights() { - return weights; - } -} diff --git a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_01_SimplePerceptron/Trainer.pde b/java/examples/Books/Nature of Code/chp10_nn/NOC_10_01_SimplePerceptron/Trainer.pde deleted file mode 100644 index f7ee88d68..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_01_SimplePerceptron/Trainer.pde +++ /dev/null @@ -1,23 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/teaching/nature -// Simple Perceptron Example -// See: http://en.wikipedia.org/wiki/Perceptron - -// A class to describe a training point -// Has an x and y, a "bias" (1) and known output -// Could also add a variable for "guess" but not required here - -class Trainer { - - float[] inputs; - int answer; - - Trainer(float x, float y, int a) { - inputs = new float[3]; - inputs[0] = x; - inputs[1] = y; - inputs[2] = 1; - answer = a; - } -} diff --git a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_01_SimplePerceptron/_10_01_SimplePerceptron.pde b/java/examples/Books/Nature of Code/chp10_nn/NOC_10_01_SimplePerceptron/_10_01_SimplePerceptron.pde deleted file mode 100644 index 67658e853..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_01_SimplePerceptron/_10_01_SimplePerceptron.pde +++ /dev/null @@ -1,89 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/teaching/nature -// Simple Perceptron Example -// See: http://en.wikipedia.org/wiki/Perceptron - -// Code based on text "Artificial Intelligence", George Luger - -// A list of points we will use to "train" the perceptron -Trainer[] training = new Trainer[2000]; -// A Perceptron object -Perceptron ptron; - -// We will train the perceptron with one "Point" object at a time -int count = 0; - -// Coordinate space -float xmin = -400; -float ymin = -100; -float xmax = 400; -float ymax = 100; - -// The function to describe a line -float f(float x) { - return 0.4*x+1; -} - -void setup() { - size(800, 200); - - // The perceptron has 3 inputs -- x, y, and bias - // Second value is "Learning Constant" - ptron = new Perceptron(3, 0.00001); // Learning Constant is low just b/c it's fun to watch, this is not necessarily optimal - - // Create a random set of training points and calculate the "known" answer - for (int i = 0; i < training.length; i++) { - float x = random(xmin, xmax); - float y = random(ymin, ymax); - int answer = 1; - if (y < f(x)) answer = -1; - training[i] = new Trainer(x, y, answer); - } - smooth(); -} - - -void draw() { - background(255); - translate(width/2,height/2); - - // Draw the line - strokeWeight(4); - stroke(127); - float x1 = xmin; - float y1 = f(x1); - float x2 = xmax; - float y2 = f(x2); - line(x1,y1,x2,y2); - - // Draw the line based on the current weights - // Formula is weights[0]*x + weights[1]*y + weights[2] = 0 - stroke(0); - strokeWeight(1); - float[] weights = ptron.getWeights(); - x1 = xmin; - y1 = (-weights[2] - weights[0]*x1)/weights[1]; - x2 = xmax; - y2 = (-weights[2] - weights[0]*x2)/weights[1]; - line(x1,y1,x2,y2); - - - - // Train the Perceptron with one "training" point at a time - ptron.train(training[count].inputs, training[count].answer); - count = (count + 1) % training.length; - - // Draw all the points based on what the Perceptron would "guess" - // Does not use the "known" correct answer - for (int i = 0; i < count; i++) { - stroke(0); - strokeWeight(1); - fill(0); - int guess = ptron.feedforward(training[i].inputs); - if (guess > 0) noFill(); - - ellipse(training[i].inputs[0], training[i].inputs[1], 8, 8); - } -} - diff --git a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_02_SeekingNeural/Perceptron.pde b/java/examples/Books/Nature of Code/chp10_nn/NOC_10_02_SeekingNeural/Perceptron.pde deleted file mode 100644 index 8936904f8..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_02_SeekingNeural/Perceptron.pde +++ /dev/null @@ -1,44 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/teaching/nature -// Simple Perceptron Example -// See: http://en.wikipedia.org/wiki/Perceptron - -// Perceptron Class - -class Perceptron { - float[] weights; // Array of weights for inputs - float c; // learning constant - - // Perceptron is created with n weights and learning constant - Perceptron(int n, float c_) { - weights = new float[n]; - c = c_; - // Start with random weights - for (int i = 0; i < weights.length; i++) { - weights[i] = random(0, 1); - } - } - - // Function to train the Perceptron - // Weights are adjusted based on vehicle's error - void train(PVector[] forces, PVector error) { - for (int i = 0; i < weights.length; i++) { - weights[i] += c*error.x*forces[i].x; - weights[i] += c*error.y*forces[i].y; - weights[i] = constrain(weights[i], 0, 1); - } - } - - // Give me a steering result - PVector feedforward(PVector[] forces) { - // Sum all values - PVector sum = new PVector(); - for (int i = 0; i < weights.length; i++) { - forces[i].mult(weights[i]); - sum.add(forces[i]); - } - return sum; - } -} - diff --git a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_02_SeekingNeural/Vehicle.pde b/java/examples/Books/Nature of Code/chp10_nn/NOC_10_02_SeekingNeural/Vehicle.pde deleted file mode 100644 index efd9bf287..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_02_SeekingNeural/Vehicle.pde +++ /dev/null @@ -1,102 +0,0 @@ -// Seek -// Daniel Shiffman - -// The "Vehicle" class - -class Vehicle { - - // Vehicle now has a brain! - Perceptron brain; - - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - Vehicle(int n, float x, float y) { - brain = new Perceptron(n,0.001); - acceleration = new PVector(0,0); - velocity = new PVector(0,0); - location = new PVector(x,y); - r = 3.0; - maxspeed = 4; - maxforce = 0.1; - } - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelerationelertion to 0 each cycle - acceleration.mult(0); - - location.x = constrain(location.x,0,width); - location.y = constrain(location.y,0,height); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - // Here is where the brain processes everything - void steer(ArrayList targets) { - // Make an array of forces - PVector[] forces = new PVector[targets.size()]; - - // Steer towards all targets - for (int i = 0; i < forces.length; i++) { - forces[i] = seek(targets.get(i)); - } - - // That array of forces is the input to the brain - PVector result = brain.feedforward(forces); - - // Use the result to steer the vehicle - applyForce(result); - - // Train the brain according to the error - PVector error = PVector.sub(desired, location); - brain.train(forces,error); - - } - - // A method that calculates a steering force towards a target - // STEER = DESIRED MINUS VELOCITY - PVector seek(PVector target) { - PVector desired = PVector.sub(target,location); // A vector pointing from the location to the target - - // Normalize desired and scale to maximum speed - desired.normalize(); - desired.mult(maxspeed); - // Steering = Desired minus velocity - PVector steer = PVector.sub(desired,velocity); - steer.limit(maxforce); // Limit to maximum steering force - - return steer; - } - - void display() { - - // Draw a triangle rotated in the direction of velocity - float theta = velocity.heading2D() + PI/2; - fill(175); - stroke(0); - strokeWeight(1); - pushMatrix(); - translate(location.x,location.y); - rotate(theta); - beginShape(); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(CLOSE); - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_02_SeekingNeural/_10_02_SeekingNeural.pde b/java/examples/Books/Nature of Code/chp10_nn/NOC_10_02_SeekingNeural/_10_02_SeekingNeural.pde deleted file mode 100644 index 66fe6590a..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_02_SeekingNeural/_10_02_SeekingNeural.pde +++ /dev/null @@ -1,62 +0,0 @@ -// A Vehicle controlled by a Perceptron -// Daniel Shiffman -// Nature of Code, Spring 2011 - -Vehicle v; - -PVector desired; - -ArrayList targets; - -void setup() { - size(800, 200); - smooth(); - - // The Vehicle's desired location - desired = new PVector(width/2,height/2); - - - // Create a list of targets - makeTargets(); - - // Create the Vehicle (it has to know about the number of targets - // in order to configure its brain) - v = new Vehicle(targets.size(), random(width), random(height)); -} - -// Make a random ArrayList of targets to steer towards -void makeTargets() { - targets = new ArrayList(); - for (int i = 0; i < 8; i++) { - targets.add(new PVector(random(width), random(height))); - } -} - -void draw() { - background(255); - - // Draw a rectangle to show the Vehicle's goal - rectMode(CENTER); - stroke(0); - strokeWeight(2); - fill(0, 100); - rect(desired.x, desired.y, 36, 36); - - // Draw the targets - for (PVector target : targets) { - fill(0, 100); - stroke(0); - strokeWeight(2); - ellipse(target.x, target.y, 30, 30); - } - - // Update the Vehicle - v.steer(targets); - v.update(); - v.display(); -} - -void mousePressed() { - makeTargets(); -} - diff --git a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/Connection.pde b/java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/Connection.pde deleted file mode 100644 index a8e75c1ca..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/Connection.pde +++ /dev/null @@ -1,29 +0,0 @@ -// A static drawing of a Neural Network -// Daniel Shiffman -// Nature of Code - -class Connection { - - // Connection is from Neuron A to B - Neuron a; - Neuron b; - - // Connection has a weight - float weight; - - Connection(Neuron from, Neuron to,float w) { - weight = w; - a = from; - b = to; - } - - // Drawn as a line - void display() { - stroke(0); - strokeWeight(weight*4); - line(a.location.x, a.location.y, b.location.x, b.location.y); - } -} - - - diff --git a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/Network.pde b/java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/Network.pde deleted file mode 100644 index 52ad9a9bf..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/Network.pde +++ /dev/null @@ -1,37 +0,0 @@ -// A static drawing of a Neural Network -// Daniel Shiffman -// Nature of Code - -class Network { - - // The Network has a list of neurons - ArrayList neurons; - PVector location; - - Network(float x, float y) { - location = new PVector(x,y); - neurons = new ArrayList(); - } - - // We can add a Neuron - void addNeuron(Neuron n) { - neurons.add(n); - } - - // We can connection two Neurons - void connect(Neuron a, Neuron b) { - Connection c = new Connection(a, b, random(1)); - a.addConnection(c); - } - - // We can draw the network - void display() { - pushMatrix(); - translate(location.x, location.y); - for (Neuron n : neurons) { - n.display(); - } - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/Neuron.pde b/java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/Neuron.pde deleted file mode 100644 index a6a14be07..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/Neuron.pde +++ /dev/null @@ -1,36 +0,0 @@ -// A static drawing of a Neural Network -// Daniel Shiffman -// Nature of Code - -class Neuron { - - // Neuron has a location - PVector location; - - // Neuron has a list of connections - ArrayList connections; - - Neuron(float x, float y) { - location = new PVector(x, y); - connections = new ArrayList(); - } - - // Add a Connection - void addConnection(Connection c) { - connections.add(c); - } - - // Draw Neuron as a circle - void display() { - stroke(0); - strokeWeight(1); - fill(0); - ellipse(location.x, location.y, 16, 16); - - // Draw all its connections - for (Connection c : connections) { - c.display(); - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/_10_03_NetworkViz.pde b/java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/_10_03_NetworkViz.pde deleted file mode 100644 index 5aa884c9b..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/_10_03_NetworkViz.pde +++ /dev/null @@ -1,39 +0,0 @@ -// A static drawing of a Neural Network -// Daniel Shiffman -// Nature of Code, Spring 2011 - -Network network; - -void setup() { - size(800, 200); - smooth(); - - // Create the Network object - network = new Network(width/2,height/2); - - // Create a bunch of Neurons - Neuron a = new Neuron(-300,0); - Neuron b = new Neuron(0,75); - Neuron c = new Neuron(0,-75); - Neuron d = new Neuron(300,0); - - // Connect them - network.connect(a,b); - network.connect(a,c); - network.connect(b,d); - network.connect(c,d); - - // Add them to the Network - network.addNeuron(a); - network.addNeuron(b); - network.addNeuron(c); - network.addNeuron(d); -} - -void draw() { - background(255); - // Draw the Network - network.display(); - noLoop(); -} - diff --git a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/sketch.properties b/java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/sketch.properties deleted file mode 100644 index 28faa5897..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_03_NetworkViz/sketch.properties +++ /dev/null @@ -1 +0,0 @@ -mode=Standard diff --git a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/Connection.pde b/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/Connection.pde deleted file mode 100644 index 8d6ec8907..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/Connection.pde +++ /dev/null @@ -1,63 +0,0 @@ -// An animated drawing of a Neural Network -// Daniel Shiffman -// Nature of Code - -class Connection { - // Connection is from Neuron A to B - Neuron a; - Neuron b; - - // Connection has a weight - float weight; - - // Variables to track the animation - boolean sending = false; - PVector sender; - - // Need to store the output for when its time to pass along - float output = 0; - - Connection(Neuron from, Neuron to, float w) { - weight = w; - a = from; - b = to; - } - - - // The Connection is active - void feedforward(float val) { - output = val*weight; // Compute output - sender = a.location.get(); // Start animation at Neuron A - sending = true; // Turn on sending - } - - // Update traveling sender - void update() { - if (sending) { - // Use a simple interpolation - sender.x = lerp(sender.x, b.location.x, 0.1); - sender.y = lerp(sender.y, b.location.y, 0.1); - float d = PVector.dist(sender, b.location); - // If we've reached the end - if (d < 1) { - // Pass along the output! - b.feedforward(output); - sending = false; - } - } - } - - // Draw line and traveling circle - void display() { - stroke(0); - strokeWeight(1+weight*4); - line(a.location.x, a.location.y, b.location.x, b.location.y); - - if (sending) { - fill(0); - strokeWeight(1); - ellipse(sender.x, sender.y, 16, 16); - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/Network.pde b/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/Network.pde deleted file mode 100644 index 2a2d2e5b5..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/Network.pde +++ /dev/null @@ -1,62 +0,0 @@ -// An animated drawing of a Neural Network -// Daniel Shiffman -// Nature of Code - -class Network { - - // The Network has a list of neurons - ArrayList neurons; - - // The Network now keeps a duplicate list of all Connection objects. - // This makes it easier to draw everything in this class - ArrayList connections; - PVector location; - - Network(float x, float y) { - location = new PVector(x, y); - neurons = new ArrayList(); - connections = new ArrayList(); - } - - // We can add a Neuron - void addNeuron(Neuron n) { - neurons.add(n); - } - - // We can connection two Neurons - void connect(Neuron a, Neuron b, float weight) { - Connection c = new Connection(a, b, weight); - a.addConnection(c); - // Also add the Connection here - connections.add(c); - } - - // Sending an input to the first Neuron - // We should do something better to track multiple inputs - void feedforward(float input) { - Neuron start = neurons.get(0); - start.feedforward(input); - } - - // Update the animation - void update() { - for (Connection c : connections) { - c.update(); - } - } - - // Draw everything - void display() { - pushMatrix(); - translate(location.x, location.y); - for (Neuron n : neurons) { - n.display(); - } - - for (Connection c : connections) { - c.display(); - } - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/Neuron.pde b/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/Neuron.pde deleted file mode 100644 index 372ba3fa7..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/Neuron.pde +++ /dev/null @@ -1,62 +0,0 @@ -// An animated drawing of a Neural Network -// Daniel Shiffman -// Nature of Code - -class Neuron { - // Neuron has a location - PVector location; - - // Neuron has a list of connections - ArrayList connections; - - // We now track the inputs and sum them - float sum = 0; - - // The Neuron's size can be animated - float r = 32; - - Neuron(float x, float y) { - location = new PVector(x, y); - connections = new ArrayList(); - } - - // Add a Connection - void addConnection(Connection c) { - connections.add(c); - } - - // Receive an input - void feedforward(float input) { - // Accumulate it - sum += input; - // Activate it? - if (sum > 1) { - fire(); - sum = 0; // Reset the sum to 0 if it fires - } - } - - // The Neuron fires - void fire() { - r = 64; // It suddenly is bigger - - // We send the output through all connections - for (Connection c : connections) { - c.feedforward(sum); - } - } - - // Draw it as a circle - void display() { - stroke(0); - strokeWeight(1); - // Brightness is mapped to sum - float b = map(sum,0,1,255,0); - fill(b); - ellipse(location.x, location.y, r, r); - - // Size shrinks down back to original dimensions - r = lerp(r,32,0.1); - } -} - diff --git a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/_10_04_NetworkAnimation.pde b/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/_10_04_NetworkAnimation.pde deleted file mode 100644 index 07596246b..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/_10_04_NetworkAnimation.pde +++ /dev/null @@ -1,50 +0,0 @@ -// An animated drawing of a Neural Network -// Daniel Shiffman -// Nature of Code - -Network network; - -void setup() { - size(800, 200); - smooth(); - - // Create the Network object - network = new Network(width/2, height/2); - - // Create a bunch of Neurons - Neuron a = new Neuron(-350, 0); - Neuron b = new Neuron(-200, 0); - Neuron c = new Neuron(0, 75); - Neuron d = new Neuron(0, -75); - Neuron e = new Neuron(200, 0); - Neuron f = new Neuron(350, 0); - - // Connect them - network.connect(a, b,1); - network.connect(b, c,random(1)); - network.connect(b, d,random(1)); - network.connect(c, e,random(1)); - network.connect(d, e,random(1)); - network.connect(e, f,1); - - // Add them to the Network - network.addNeuron(a); - network.addNeuron(b); - network.addNeuron(c); - network.addNeuron(d); - network.addNeuron(e); - network.addNeuron(f); -} - -void draw() { - background(255); - // Update and display the Network - network.update(); - network.display(); - - // Every 30 frames feed in an input - if (frameCount % 30 == 0) { - network.feedforward(random(1)); - } -} - diff --git a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/applet_js/NetworkAnimation.pde b/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/applet_js/NetworkAnimation.pde deleted file mode 100644 index fd5d64473..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/applet_js/NetworkAnimation.pde +++ /dev/null @@ -1,238 +0,0 @@ -// An animated drawing of a Neural Network -// Daniel Shiffman -// Nature of Code - -Network network; - -void setup() { - size(590, 360); - smooth(); - - // Create the Network object - network = new Network(width/2, height/2); - - // Create a bunch of Neurons - Neuron a = new Neuron(-300, 0); - Neuron b = new Neuron(-200, 0); - Neuron c = new Neuron(0, 100); - Neuron d = new Neuron(0, -100); - Neuron e = new Neuron(200, 0); - Neuron f = new Neuron(300, 0); - - // Connect them - network.connect(a, b,1); - network.connect(b, c,random(1)); - network.connect(b, d,random(1)); - network.connect(c, e,random(1)); - network.connect(d, e,random(1)); - network.connect(e, f,1); - - // Add them to the Network - network.addNeuron(a); - network.addNeuron(b); - network.addNeuron(c); - network.addNeuron(d); - network.addNeuron(e); - network.addNeuron(f); -} - -void draw() { - background(255); - // Update and display the Network - network.update(); - network.display(); - - // Every 30 frames feed in an input - if (frameCount % 30 == 0) { - network.feedforward(random(1)); - } -} - -// An animated drawing of a Neural Network -// Daniel Shiffman -// Nature of Code - -class Connection { - // Connection is from Neuron A to B - Neuron a; - Neuron b; - - // Connection has a weight - float weight; - - // Variables to track the animation - boolean sending = false; - PVector sender; - - // Need to store the output for when its time to pass along - float output = 0; - - Connection(Neuron from, Neuron to, float w) { - weight = w; - a = from; - b = to; - } - - - // The Connection is active - void feedforward(float val) { - output = val*weight; // Compute output - sender = a.location.get(); // Start animation at Neuron A - sending = true; // Turn on sending - } - - // Update traveling sender - void update() { - if (sending) { - // Use a simple interpolation - sender.x = lerp(sender.x, b.location.x, 0.1); - sender.y = lerp(sender.y, b.location.y, 0.1); - float d = PVector.dist(sender, b.location); - // If we've reached the end - if (d < 1) { - // Pass along the output! - b.feedforward(output); - sending = false; - } - } - } - - // Draw line and traveling circle - void display() { - stroke(0); - strokeWeight(1+weight*4); - line(a.location.x, a.location.y, b.location.x, b.location.y); - - if (sending) { - fill(0); - strokeWeight(1); - ellipse(sender.x, sender.y, 16, 16); - } - } -} - -// An animated drawing of a Neural Network -// Daniel Shiffman -// Nature of Code - -class Network { - - // The Network has a list of neurons - ArrayList neurons; - - // The Network now keeps a duplicate list of all Connection objects. - // This makes it easier to draw everything in this class - ArrayList connections; - PVector location; - - Network(float x, float y) { - location = new PVector(x, y); - neurons = new ArrayList(); - connections = new ArrayList(); - } - - // We can add a Neuron - void addNeuron(Neuron n) { - neurons.add(n); - } - - // We can connection two Neurons - void connect(Neuron a, Neuron b, float weight) { - Connection c = new Connection(a, b, weight); - a.addConnection(c); - // Also add the Connection here - connections.add(c); - } - - // Sending an input to the first Neuron - // We should do something better to track multiple inputs - void feedforward(float input) { - Neuron start = neurons.get(0); - start.feedforward(input); - } - - // Update the animation - void update() { - for (Connection c : connections) { - c.update(); - } - } - - // Draw everything - void display() { - pushMatrix(); - translate(location.x, location.y); - for (Neuron n : neurons) { - n.display(); - } - - for (Connection c : connections) { - c.display(); - } - popMatrix(); - } -} - -// An animated drawing of a Neural Network -// Daniel Shiffman -// Nature of Code - -class Neuron { - // Neuron has a location - PVector location; - - // Neuron has a list of connections - ArrayList connections; - - // We now track the inputs and sum them - float sum = 0; - - // The Neuron's size can be animated - float r = 32; - - Neuron(float x, float y) { - location = new PVector(x, y); - connections = new ArrayList(); - } - - // Add a Connection - void addConnection(Connection c) { - connections.add(c); - } - - // Receive an input - void feedforward(float input) { - // Accumulate it - sum += input; - // Activate it? - if (sum > 1) { - fire(); - sum = 0; // Reset the sum to 0 if it fires - } - } - - // The Neuron fires - void fire() { - r = 64; // It suddenly is bigger - - // We send the output through all connections - for (Connection c : connections) { - c.feedforward(sum); - } - } - - // Draw it as a circle - void display() { - stroke(0); - strokeWeight(1); - // Brightness is mapped to sum - float b = map(sum,0,1,255,0); - fill(b); - ellipse(location.x, location.y, r, r); - - // Size shrinks down back to original dimensions - r = lerp(r,32,0.1); - } -} - - diff --git a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/applet_js/processing.js b/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/applet_js/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/applet_js/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/sketch.properties b/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/sketch.properties deleted file mode 100644 index 28faa5897..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/NOC_10_04_NetworkAnimation/sketch.properties +++ /dev/null @@ -1 +0,0 @@ -mode=Standard diff --git a/java/examples/Books/Nature of Code/chp10_nn/xor/Landscape.pde b/java/examples/Books/Nature of Code/chp10_nn/xor/Landscape.pde deleted file mode 100755 index 40ef0a733..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/xor/Landscape.pde +++ /dev/null @@ -1,73 +0,0 @@ -// Daniel Shiffman -// -// "Landscape" example - -class Landscape { - - int scl; // size of each cell - int w,h; // width and height of thingie - int rows, cols; // number of rows and columns - float zoff = 0.0; // perlin noise argument - float[][] z; // using an array to store all the height values - - Landscape(int scl_, int w_, int h_) { - scl = scl_; - w = w_; - h = h_; - cols = w/scl; - rows = h/scl; - z = new float[cols][rows]; - } - - - // Calculate height values (based off a neural netork) - void calculate(Network nn) { - float x = 0; - float dx = (float) 1.0 / cols; - for (int i = 0; i < cols; i++) - { - float y = 0; - float dy = (float) 1.0 / rows; - for (int j = 0; j < rows; j++) - { - float[] input = new float[2]; - input[0] = x; - input[1] = y; - float result = nn.feedForward(input); - z[i][j] = z[i][j]*0.95 + 0.05*(float)(result*280.0f-140.0); - y += dy; - } - x += dx; - } - - } - - // Render landscape as grid of quads - void render() { - // Every cell is an individual quad - // (could use quad_strip here, but produces funny results, investigate this) - for (int x = 0; x < z.length-1; x++) - { - for (int y = 0; y < z[x].length-1; y++) - { - // one quad at a time - // each quad's color is determined by the height value at each vertex - // (clean this part up) - noStroke(); - pushMatrix(); - beginShape(QUADS); - translate(x*scl-w/2,y*scl-h/2,0); - fill(z[x][y]+127,220); - vertex(0,0,z[x][y]); - fill(z[x+1][y]+127,220); - vertex(scl,0,z[x+1][y]); - fill(z[x+1][y+1]+127,220); - vertex(scl,scl,z[x+1][y+1]); - fill(z[x][y+1]+127,220); - vertex(0,scl,z[x][y+1]); - endShape(); - popMatrix(); - } - } - } -} diff --git a/java/examples/Books/Nature of Code/chp10_nn/xor/code/src/Connection.java b/java/examples/Books/Nature of Code/chp10_nn/xor/code/src/Connection.java deleted file mode 100644 index d8415d2a6..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/xor/code/src/Connection.java +++ /dev/null @@ -1,47 +0,0 @@ -// Daniel Shiffman -// The Nature of Code, Fall 2006 -// Neural Network - -// Class to describe a connection between two neurons - -package nn; - -public class Connection { - - private Neuron from; // Connection goes from. . . - private Neuron to; // To. . . - private float weight; // Weight of the connection. . . - - // Constructor builds a connection with a random weight - public Connection(Neuron a_, Neuron b_) { - from = a_; - to = b_; - weight = (float) Math.random()*2-1; - } - - // In case I want to set the weights manually, using this for testing - public Connection(Neuron a_, Neuron b_, float w) { - from = a_; - to = b_; - weight = w; - } - - public Neuron getFrom() { - return from; - } - - public Neuron getTo() { - return to; - } - - public float getWeight() { - return weight; - } - - // Changing the weight of the connection - public void adjustWeight(float deltaWeight) { - weight += deltaWeight; - } - - -} diff --git a/java/examples/Books/Nature of Code/chp10_nn/xor/code/src/HiddenNeuron.java b/java/examples/Books/Nature of Code/chp10_nn/xor/code/src/HiddenNeuron.java deleted file mode 100644 index 3c8d7945d..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/xor/code/src/HiddenNeuron.java +++ /dev/null @@ -1,20 +0,0 @@ -//Daniel Shiffman -//The Nature of Code, Fall 2006 -//Neural Network - -// Hidden Neuron Class -// So far not necessary to differentiate these - -package nn; - -public class HiddenNeuron extends Neuron { - - public HiddenNeuron() { - super(); - } - - public HiddenNeuron(int i) { - super(i); - } - -} diff --git a/java/examples/Books/Nature of Code/chp10_nn/xor/code/src/InputNeuron.java b/java/examples/Books/Nature of Code/chp10_nn/xor/code/src/InputNeuron.java deleted file mode 100644 index a2191632f..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/xor/code/src/InputNeuron.java +++ /dev/null @@ -1,23 +0,0 @@ -//Daniel Shiffman -//The Nature of Code, Fall 2006 -//Neural Network - -// Input Neuron Class -// Has additional functionality to receive beginning input - -package nn; - -public class InputNeuron extends Neuron { - public InputNeuron() { - super(); - } - - public InputNeuron(int i) { - super(i); - } - - public void input(float d) { - output = d; - } - -} diff --git a/java/examples/Books/Nature of Code/chp10_nn/xor/code/src/Network.java b/java/examples/Books/Nature of Code/chp10_nn/xor/code/src/Network.java deleted file mode 100644 index c0854712d..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/xor/code/src/Network.java +++ /dev/null @@ -1,143 +0,0 @@ -// Daniel Shiffman -// The Nature of Code, Fall 2006 -// Neural Network - -// Class to describe the entire network -// Arrays for input neurons, hidden neurons, and output neuron - -// Need to update this so that it would work with an array out outputs -// Rather silly that I didn't do this initially - -// Also need to build in a "Layer" class so that there can easily -// be more than one hidden layer - -package nn; - -import java.util.ArrayList; - -public class Network { - - // Layers - InputNeuron[] input; - HiddenNeuron[] hidden; - OutputNeuron output; - - public static final float LEARNING_CONSTANT = 0.5f; - - // Only One output now to start!!! (i can do better, really. . .) - // Constructor makes the entire network based on number of inputs & number of neurons in hidden layer - // Only One hidden layer!!! (fix this dood) - - public Network(int inputs, int hiddentotal) { - - input = new InputNeuron[inputs+1]; // Got to add a bias input - hidden = new HiddenNeuron[hiddentotal+1]; - - // Make input neurons - for (int i = 0; i < input.length-1; i++) { - input[i] = new InputNeuron(); - } - - // Make hidden neurons - for (int i = 0; i < hidden.length-1; i++) { - hidden[i] = new HiddenNeuron(); - } - - // Make bias neurons - input[input.length-1] = new InputNeuron(1); - hidden[hidden.length-1] = new HiddenNeuron(1); - - // Make output neuron - output = new OutputNeuron(); - - // Connect input layer to hidden layer - for (int i = 0; i < input.length; i++) { - for (int j = 0; j < hidden.length-1; j++) { - // Create the connection object and put it in both neurons - Connection c = new Connection(input[i],hidden[j]); - input[i].addConnection(c); - hidden[j].addConnection(c); - } - } - - // Connect the hidden layer to the output neuron - for (int i = 0; i < hidden.length; i++) { - Connection c = new Connection(hidden[i],output); - hidden[i].addConnection(c); - output.addConnection(c); - } - - } - - - public float feedForward(float[] inputVals) { - - // Feed the input with an array of inputs - for (int i = 0; i < inputVals.length; i++) { - input[i].input(inputVals[i]); - } - - // Have the hidden layer calculate its output - for (int i = 0; i < hidden.length-1; i++) { - hidden[i].calcOutput(); - } - - // Calculate the output of the output neuron - output.calcOutput(); - - // Return output - return output.getOutput(); - } - - public float train(float[] inputs, float answer) { - float result = feedForward(inputs); - - - // This is where the error correction all starts - // Derivative of sigmoid output function * diff between known and guess - float deltaOutput = result*(1-result) * (answer-result); - - - // BACKPROPOGATION - // This is easier b/c we just have one output - // Apply Delta to connections between hidden and output - ArrayList connections = output.getConnections(); - for (int i = 0; i < connections.size(); i++) { - Connection c = (Connection) connections.get(i); - Neuron neuron = c.getFrom(); - float output = neuron.getOutput(); - float deltaWeight = output*deltaOutput; - c.adjustWeight(LEARNING_CONSTANT*deltaWeight); - } - - // ADJUST HIDDEN WEIGHTS - for (int i = 0; i < hidden.length; i++) { - connections = hidden[i].getConnections(); - float sum = 0; - // Sum output delta * hidden layer connections (just one output) - for (int j = 0; j < connections.size(); j++) { - Connection c = (Connection) connections.get(j); - // Is this a connection from hidden layer to next layer (output)? - if (c.getFrom() == hidden[i]) { - sum += c.getWeight()*deltaOutput; - } - } - // Then adjust the weights coming in based: - // Above sum * derivative of sigmoid output function for hidden neurons - for (int j = 0; j < connections.size(); j++) { - Connection c = (Connection) connections.get(j); - // Is this a connection from previous layer (input) to hidden layer? - if (c.getTo() == hidden[i]) { - float output = hidden[i].getOutput(); - float deltaHidden = output * (1 - output); // Derivative of sigmoid(x) - deltaHidden *= sum; // Would sum for all outputs if more than one output - Neuron neuron = c.getFrom(); - float deltaWeight = neuron.getOutput()*deltaHidden; - c.adjustWeight(LEARNING_CONSTANT*deltaWeight); - } - } - } - - return result; - } -} diff --git a/java/examples/Books/Nature of Code/chp10_nn/xor/code/src/Neuron.java b/java/examples/Books/Nature of Code/chp10_nn/xor/code/src/Neuron.java deleted file mode 100644 index 234780016..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/xor/code/src/Neuron.java +++ /dev/null @@ -1,81 +0,0 @@ -//Daniel Shiffman -//The Nature of Code, Fall 2006 -//Neural Network - -//Generic Neuron Class -//Can be a bias neuron (true or false) - -package nn; - -import java.util.ArrayList; - -public class Neuron { - - protected float output; - protected ArrayList connections; - protected boolean bias = false; - - // A regular Neuron - public Neuron() { - output = 0; - // Using an arraylist to store list of connections to other neurons - connections = new ArrayList(); - bias = false; - } - - // Constructor for a bias neuron - public Neuron(int i) { - output = i; - connections = new ArrayList(); - bias = true; - } - - // Function to calculate output of this neuron - // Output is sum of all inputs*weight of connections - public void calcOutput() { - if (bias) { - // do nothing - } else { - float sum = 0; - float bias = 0; - //System.out.println("Looking through " + connections.size() + " connections"); - for (int i = 0; i < connections.size(); i++) { - Connection c = (Connection) connections.get(i); - Neuron from = c.getFrom(); - Neuron to = c.getTo(); - // Is this connection moving forward to us - // Ignore connections that we send our output to - if (to == this) { - // This isn't really necessary - // But I am treating the bias individually in case I need to at some point - if (from.bias) { - bias = from.getOutput()*c.getWeight(); - } else { - sum += from.getOutput()*c.getWeight(); - } - } - } - // Output is result of sigmoid function - output = f(bias+sum); - } - } - - void addConnection(Connection c) { - connections.add(c); - } - - float getOutput() { - return output; - } - - // Sigmoid function - public static float f(float x) { - return 1.0f / (1.0f + (float) Math.exp(-x)); - } - - public ArrayList getConnections() { - return connections; - } - - -} diff --git a/java/examples/Books/Nature of Code/chp10_nn/xor/code/src/OutputNeuron.java b/java/examples/Books/Nature of Code/chp10_nn/xor/code/src/OutputNeuron.java deleted file mode 100644 index abe8daee4..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/xor/code/src/OutputNeuron.java +++ /dev/null @@ -1,7 +0,0 @@ -package nn; - -public class OutputNeuron extends Neuron { - public OutputNeuron() { - super(); - } -} diff --git a/java/examples/Books/Nature of Code/chp10_nn/xor/data/GillSans-16.vlw b/java/examples/Books/Nature of Code/chp10_nn/xor/data/GillSans-16.vlw deleted file mode 100755 index 380eee76c34bd39bdd163b4b9c0bda5407db9a69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28543 zcmd6vXRz#AcGvZ0WRSr!2v8NM0Nr`QMqmVX6B-+u&=}k%G{H@3k_K!V!_Wjn6Pu6y zwX68n-+(3=2SgRAph}ozgGnWFEHap!!7xyp-+%4B&(%9V_sn~5?##RE9JRJ~TzjRx zc94=J`IaO}z9ZLn=6b>PSzIaCN4RpX4~J*Pzr`hZo9o-nE~Q0i2&mk5;QCCidD{2k z`Ljd(hwt}98c_z{pI_nk z?ZYL!B77bJrNvA5MEC&&)RyR{OZY_S24Ef+*5V_uxHYip-#~=wnxz5hx033 zo~rW;iC2H0O8X+>RbQm3@wY!jC1Oyt*Fi!#c#rHs^KzIMP(lQ{}$+QT)8zj}K{2@%<+} zllCQ~#r9O6t_T|fdKNumTI~CmhB(Qjc%k%|_7e$5y|pw45GVLaT(QnrZ!GtdL)u&> zV%kp$X_1!m_O{QY{Z!J_zj&!!gr7!0&rh}Y(~191Tu+tz8KIo`_qY#V7Rsnj@nYWI zEioii>p;H2AsvzN*fBNK=`| zc>X-%B5xn-!_Oy8eR#^&{emaT5oPcT`Hei#ecp#(#Is~fxO}GMNI+Q7b4k9G{uq~! z5-0vdKIk6d7ZVVkPwC1pAztN_7SjnDd^x|uE#f-I^DBst?ZtE}#Lq9~QeN4gs4D~w z4*bSCAGi0*LRyShz9=MROl^R!<{ zobs!kSU%!%3~3Qh<%?;*im>PsFQrBJ)dXT)il3+bnrG5}ZOAKn>YBIrRXnS$c^Z!f zzm8wYv(h9l$`|3+6VUTheK>_QwG-0`8vF)+RZjhgeX#_7ej}I4C|!455q=YanE!E| zznQey*5kC_LYnkE_CazS;kOcyZb~1boJBsIiF;MK-xl(VHjxGd4Sol|szaCRe1RX@uD&Q7;ZGBIRob6zzCzg+C-xT6wIo%`t1p+D~8jCIp$G-o?@cdNTH$Rj1mq-&1v7ExO z&c7VWMINfX2!Dlup66+?++Pi8k_V;F%l$Q;)rR=4w7FbQJS(qw7wHr0{OiPthEZSU zb^eWK(*EW%X@BdPw7*T7+KBB5=Lmm?K$J_#pY$T)`F9D&GP=+C_xE^?dKBd|mizn9 zr2T_u(*7Z7!c#b?&N=`7(JW2rbDI5Qo`qlJyYP&-{F9KTJ}Q0QhkyD^+CO_H?VmrB z_Aj1E`+Gim?!nY4fR zOxnK>ZA4x9teGwU50BG$j(qr!Aua04yxf0!Chfn3wAk-CZ~rT4>bvNsYu@+&_DtG; ze26!7s+UZZzT}pbyvO!|C@mN@Kpc)&ogNse7;4}H@!X|kWMDku9Hbtu*u==mYp&p6)bE?i=o?B~3k;$xcZr+k;E@Ra?01uh@{ zYSPq(Xr{i++WYV~@GP2$mXS6D1uwoUKavNfNgh7qr7d{z-9p-T;VvG})4n^;!ZG$^ zM$Z@Dwfw|1rO(>?i29&5BA!YMc)l&3D_-)TJgOtW+v>0KM*W-B`L=XXeN&vu=!$hJ zUYE-0nx~2HN{jL*+5~u8{1fklzsf03tn>2-Oa6qDXg)8u;W?Iz^%5m`yXPnNPigc1 zeL2su9i=H8;O(y<@QSq0`DW5okLdM?X5T8iE7~Ysm)Z{SarH&?isfeX{J8k=WLmyU z4{o`4i{AbZZn1XD#+B(UNvq`S`lH*?QtmE0*X8csyCq@!?K@W`u5VqQG+Ek;Yz_3U zS^~**Op@b7Aalzk8F)%+S0<@jC3orm#C1L2+;qE5?#{Br{g5QP5$YFYNr_2EgpVxRcp>QN#)MT z%B?!u8(f+kpw!f_-9k;CdUtgf754q~_;>Aw?t4hxwYd$w=z4Y?lu~mGw`r+)9Kmp) zf%}m*dRId{=k7(4Wmee#CPk!52R>KTq;6jZ*DIL2DQUnh1Xn%?e_%e03bvSp-9u9QpCbF&cPmZC0E5TH{vVz)}u5VEbh zVO1we_CocfxX~~`6fOi>(SKw7q%>t!2h?bHsjC<3-kryTyCp5XU8PAoIBM9y%Coz4 zo6OZqYR$ZSfV#;iRSZbB!60;!qR5AdACnVNE$J5B=oSn5OlHeN04{q#@PTy;<}NE8 z1UVzgw<5_`tJPwm8q&6Hn zC^y_`El5(j+0uJ2rO@;2?g&Ml(g>CHt@u^DdnZkT)*aFa6S>o(-Jx{h2J+XG-6dP+ zAQ?#X2n?-LN`g=?)1xbTmp}85@b5NY=M4jWb+`QhdkavY!-W~{yCeoM$&onR^aP!e zMa4>XKm_az1?<)_y`XQJkfT7B=mq3Ych)KG|fEkqsSFG}+ zAm=1KxLGY1l2Xq)m9LQuAPcqLOfscdVz+q6y+Ge|AKWH&BjRZ=ZVx?%Sn@1hDZf!S z+~HQX0N}5Q0_G9=uQy=W1x0>&zwSi|p;Oq?ji5 zq~Ls6kFr+usG;|&vUWFc-V|r#9Qg;*d~(-*a{a=K{J3y8?1A-7#M>vujcjH}vdn~} z+}hx@R`HW)!dT!|GNKv}OoeJU$iAYPBSuVsKCRD?$%JR+d$ZNxA~E){8<|B|QHkDp z8bn`F3DO7N8CPodAgA1&!q-4R!NsL2YNFgFzLB(Y}Y z!eC(4WVxg?K!#)kH!p!?c2mFFfQkt#3gYR3E=l07SlMozcGacAXn^_23mz=(kd_`% z$1zzTL7DuN;ervM0&FZ+;hG_TqnMG);7%uQsWE4(aT-O!?^1Vaic7yRBvd)dj({W@ zsX_jLSYm!p*^WByQKyphB1x3WAG@kvQU=)r%;TW~cpo5dySDaPL`<>qVxYw1Lv50~ zV2iyU5r$M$wGT#PG+dobo)tz& zvKlEfPgF9Xp_$(Au+k8-7r$l78Dc~i1*&`_?S>ct2=;Ej=|}3e%;aV~q7*D8FpQFX zpLz5=O*CdKf)-dMh8HBfuGS|p2J5;Jav8?$_F!?;mj|L{;!^-KI`M%)AO=;>ULx1Z z8p}()$q!W>t;~$Odn#h5O)^D?MQ2TTN-!iFE!LX@y;y_};_6^FhsEDm|t%x#p|7}Q8xw+pfzpeEG*hAM;)i*haW@5yhOv-T zhD96u@pU)MS*%1M1;W}Him0rz@krx9;gIqmfbZhjI5W#P3W5Z>ya_x^mW}U# z%;bdnN=cB1!E3TcMuJE5>FQ1j(#=VJ2SFx|4B-|maJ}UGS}Zj@3dYf&3^(hdGTiGh zkS2>pBb_gXB*lrK35)PCse*!S2xbferH{=K{7E<%>CpQqff-J86eyS#gW_NmGy2K+ zg%WJ`yQPUBGd3@t(hUX$cV4X_1Uy12Y@}hBsz?aq#@!u|{V?h>Duag#0))WChw(>8 zbkg`Q2MN*gB9LS0V3Ty>&e-bR#a5JeM~@E`g++vR36R-_b=39lwkwcr;E3v6+8pDk zdm(Q*jE{E>rH6f|A=TITXf6WzOjZq32(e%JY>^O>)R%<7SAY=IW=KCKgl15J4x9VX z_a_Ju*sclB$`hi15TKzU#0a6;K;jAE7YKOFF-6nm9H^Kybp9S1RBlKkJ8T}`Q54if z4!y(S!(r?}+Bk*j)i|el;)(&ALC#ww8dMCe4 zQzZ~l;%0H5@Nwi|ExDU$sjVxhksV!ud;t3IU04=bs$3J53#&-v8&s|88!F`sb5QXe zXv4INsSDk>IE)RZY5!%g{CWJJ9_nLq59uY`)Ho=3l zHsR62kWI!lg%a~eD%@*8y@M|VXf;4!0<EzExUo$q$yLekVN&QWkQk$0K zvMS4pS?hbpW|6b<03)fO10hX=S_!sUN~1qxg$i-iVVA-BWBiDk(E>2{y)ahU~uQY zVeQFHhfJ>BX!43i@!!!l5R6=~aKXF{L)OwOKORdh8K1UF!;e)?99G>}V;S(6u?sR{ zlQhaqH}|rkiA+AU2JHLxdaS)R*!qeT=??$oyt^}4rXr@+9tRF)% zyO*t2%9$bqM+qe}8CJ8=Ue-=ED_4GIZ!EKrj_8~(DyJdFq@`-qdZrG-7AydRWrY$- zJ^KbDbGu&F7;iEatnLa)SyEwn7rRrx;E->(scZ>$kM?mak7oAIvQ=_dv=;47MoG2j zRnq@@;~RYtrd?!U_NKa!f#bkRLW9TMQ3uL@v=ue@e3gm71A@9{jHJSY+b!r>KFS!e zJa4^}o;HWmk^Ikd+IETVQr06CU%J69#AzB9i**Z6?}$vcd*PKOs|}a{%B2E!S2$b} z!DP>-m6n9I!H#MrJ!W{~UfT-wE-Cwndlb`$#dwtx*qynV?($ba;VMBIMq56iN8WM{ zckC>>Lq6=_!ZZVCziGP(9UYj|&j0RAos$|SmaJajoS@AI8GbZj1z$Ie_ zsQJQFrEo`-i>!MXD#=Bt$PNDPCee*+$C~N$1QU_zR{S}lPOLT4U=w}#$@}uHW*6>+ z__OIK&>H1vn@L_tq;H-h>Cp_I8e+MV?m{J?M=-|&Q*~RsV-=&7fn;6W92=gMzSmUV z``=P_ErxrgC!gxW;KN;t4rzu-4A`h-U%NS`q zx6Vo;g(}O@UP6KsWjio_v>%W$eT+$UH9 z7Pcf?kt@_gSE0tuEjs$$s_!?q(#oWnK4UKYG@G*Yq<~uX$f~_sApbiamlx_2U~UnA z=>#NSo+Lri4WFI46XDjZKX|$89mhprf+XhDHf*rVh>4K)^K01n@Ll0j6riWYgMXCy zUR!D`Wo5w`F@j1kH7UD1U#1IJbT0pd|75GLncvi95rekyXXMS=4kD~JwXyB~(4wC+ zHO2|#1-{t&but)7ET@$%c2YU0OODd7Tvkl`=zE({8erTnx_e#sNUas7SrhrP$5-o* z?vT}t(9nui-Il##Tt5B@tb;F`dSTKoI`T=|SPuMA+g*^)^CXNWrcCxnFrKs4V zbi=;iur+>1y6^XMQto$qH*9yN65eZ8HMV!b?J21v8R>c?jb7@IYuo>o8ML*VJ=>(% zo-YSDMz1!zT7pICH3Zr!w4azhE2P02Ig*9uG=yf#a(|dtV-}faETP*W5rvVWYAy%t(AmZ$|}8J&lIb+ax3VP$D8qD4#uOyn5Un0@&&Hc`~pFlJ$nbcfFyP^|S zew_l*7@POg)f0^r`Y(|Z(K?ql2sWFT5DhbcN3se;LquR@B-$Mr_%=jK$_NkJ&JyxC zRca9j7!O`kHC(IVJTQ_CTBle1Jk6Svj1lsy#i8#tQ+5<^&`9sNozH^hD-azYxo36!Of zHBmW~{^pTqVa*^np+&hToAwRK0otKeh_*sf6d!_;A*A`9j{`6GrhEYXd9R^|vJ4eR zxC=1N%cPHu7J#}vqZdZ^;-&}6^ifL!4qq( zrDVzX)p6XaCvwtSdnXUp^g*troI5Pz4!g2)J2MhVvC{_E!5rPJg?Q&PlBc|TZP?3| zlA350h0T9xo-}>SuLp*b7?dMQa{=;`*;IS_pf^wriKaIzV&T#J6brU;jsnzYFE4t0 z6L4;iHpmDajnSq_gilVA=%H*@)dQj50Guw5~!?s{W-V}pSvL_F4u zu3x|AQwt!l*-O;qYytRxYG}9VUVB5`QC_5+1?&cAXh#-*_nUUzzut2gDb5f7TKMF@ z+AJ6A=i7m*R{~!0%ZpX8E_O;v&!3Vt4 zpY1mu5Bs$P*bmPWo@;<|bG*Fq2Le2<^~{%J(4+k4$-rxfpo(omNvWN$k83&tA>+x{fk6H#dDA(J4IFA$0U6`CQEWSAh zP=x7vV0p4(&@hy&KpXNNv>VB*5n2S)4!g~Lm?deCccbTp z9GVgjV_jb0VRg2?7MmUK9@MRB(lWY0&OFZYX`#bHc%l^Vh+=h%iPvCD#Ru2lb$nZE z(`zR1tY@+QF29BeH4{J0*!;#Nn~SV_@T!oS(|#RTO0RWB20u%#lAV!ZHdMJ@dyC<) z5H*LR6BNvQ>nkDl;=OyOcC;#*=xj&HYfm5C*$!cm?wKqbtRH3;Hdq*bHETg1D1OC( zVcq}|`)S{MsLDfvv<1uEOX1gQXg)caf`c*9wuf$*#_R z)a(a+y3c+j)mCp(*uwO{M$Cf4eI%WVPdD%7GA-$6#y0iQ?q#0YdLg5WxQzv#zzf_NbS8pMZ#J0uZwQ1 z+S|6!#j$RU=CXOR<%O7+@Y?uO`dS$gXa?7%xR}d}?eNA|2SI?>#V4KI$h7!tFGC$* zyWa0SF<_0HS8K9L({H`;v+`rxlI7jJVcfBUX&KvU*Civ#l`T~5NM5v`KOwTV=j!(z zKjGn(+E%M=7wXJ*o(=nw{;NjUq`KLyxodYhS@oU_%=vi&Y|5fQSk$X94NMWiMN5?L z`zQ+b$Dh%P)+a8snSRiMZGXRpcKV|+6oShdlz7r@f+l(*2|GeDTVb?Ze0b%1+u{;c&5i(z2t&8mvxaWH3-1ekM1mMlReU zy>)lu)i5KJ#MjhDWqn(|o~M3o)5gfbJEJW6)?-zTL3rMCJsfD^2pQI%w?a5>zj^7G zYdKyojK7bgDa+p5eDBk#M~o_QLKf!65mQ?$dkx1|Xk&2*ZG;6c{6(Ztz;TWMVfW`X zotdFcThQ@KI;PlcRQOe-n%93r^R^AH?Y!4=P>1ol^6zIOM!XG5&km;pzH;oNzrW^2 zF@@e5a#qV95jdR^{@)3&xl!~yND>kny5-NF@OJiYmp^(%d#e>Yva!Vw(271-jwEjp zXg^QUruu!w$je)Wyg+FrIS*a~M{8R$h{mLYE z-`a_C#!&Rhp7No-ZLc;eKLcRARuh$E%ZQu3?*l|QF-K7o{|~e=aBQ3*OH__eqejyA zUp1p8%V)Ve>aa+9-^>nOe9~AaRc{^y3^9XWh2u;*`U+8uJ{e|;-LFr@(V&z!*G2uk z)^%((gXlA#xoW2*6AiKkK$zjT3L)ZS~kAAv-|*>YUhnia4A>UYvEYSS0hsA08up!hEwWaYrwAQeOP=mpDo5cAw*kK z1!<1oQRbp00LQzi@JF@XI7^O+RU3Z(Z*QyfGBL#vAzVE_X}}PhMAg@eB#I-0QVGcM zDS2_F06d28AzH)oLHiPNVcy8T7hp-2{PRRIELn$J`y&KkRO|5vVi?g+dH9hUPrhRrE zw+Sj<>)4y#KECXyG3P5C&0*cRGw=D_$C?gS)J79PQHGIS6E2SshU~IMt#_!r&FZl+ zr5!RQKj%zYr?jF>o$SLfJa8!U5|;OCcMqq`z*NJyF)k#XU#5i* zES&VVEsNl%$z~y#r6s3o7D+?&M&u6Pm|@kK!w5+#Uar6Gw`Y=!gtpWk;L=qc1iepK zRL3m$B*)f|5Z5a!GTcYL44;moMrN#Z{Qdr275eo_bPGl)Fu<7~@Rmq94*HnZ4hx_M z0Y-y2ZjqP>XqhQNd`9K9D;e}M#MZ7~-Z?^>?pg6u+{mX?80c4fxTm~(*X$%J$D2cM zmt1Gix^Rk|S70>W+9?!9ISymtPVccL<^=eeSeP*ArWY3ro&8iH|4k3xs*)X&9n?7o z=)fo~u55UcnPV7dmq1i&5W_vGW{F9|M=(EHp=dwJ5;|8rEVSPOGha>?!?|qAafVgJ zWo9DXy;n|D{L})Rh!ibjCM%PzcN;9M`XvBUcy?Os##ZP;27%dE1yD=_G?7=g569!F zh;j6{z%;Ix`p}okO3YT&Qd5F&fytGrP$vH-5_J|}?LW~|=`G-D89rpisG#EHFZiLw ziir|+=KS!qt=&YLe>&dwm;1vLsjI=Bbo`W)gt@-=lHHr6zNfoOase9vHVIHIbC5fC z^BWp65PaLsLl*++O4Lnv(hj{E%4dBL*}|4>drs(@WWy%&a86`lUcL0k_T(-aE%Y+h z0~oRGsZh-x;+Ua+Nl*;r@Og|=*ZR}_I8&2`9qWR)t>Hqvc7z?=iUqTQ zhpuQL-9teT!4&Ao|AVk2n?b8YwO~8V2Ru`o0olWtV5=aZgUDjoBftrco2hsgfi8Fw zoi85T0X-n+O($5`scVnfsePfY=GsCV*6ohi$Mib z9?rsFwrj9sVsO#D=VKhvhJSN54Q0(dP3X|%xD69~>pIwtS${QeX@A51`Q;vpUsZ&V*o z`u-HnO%v40qF8M;bPD_%F0zdeGO6gb7c@SOHR*{8j=Vd-4Kpjt;F+l{gaLmD$n}NF zTQD;Cf$4U)+if>{KI!BEQ{^Gg;+L0XVSI^FekL>pDuUrNSQ>AMDfB@qK5>aC-}y!% z1Dd_P$-6N-&iU{X;nWQOHHC%hWR^G(nYvY9PjY#jo61t zUL2-XTOdVpmB5bY#wtS0y_QC2MwKSrgVP|nj{0ItM?n^uaPXZ)dnXr%G5`aUOlttW zDH%cEoQS{+4p|IKRbHmZ3hKamfZA_W`X|`=kfgDn@4F!c^0EYJM|x$HL0)%u?$Xdo z>GHMEOWg-de#+wWUhnSdyc*1J5IGJbXcgVOO)cZg7C(3A?Tu~C!i)NFVH`cUOU*lb p<`Agd5!!RtR6_MLWPPIgHPXLqH~W&W{Mg67?4!r8N*+RQ{eM>Vwm|>@ diff --git a/java/examples/Books/Nature of Code/chp10_nn/xor/xor.pde b/java/examples/Books/Nature of Code/chp10_nn/xor/xor.pde deleted file mode 100755 index eab37c5c7..000000000 --- a/java/examples/Books/Nature of Code/chp10_nn/xor/xor.pde +++ /dev/null @@ -1,114 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/teaching/nature - -// XOR Multi-Layered Neural Network Example -// Neural network code is all in the "code" folder - -import processing.opengl.*; -import nn.*; - -ArrayList inputs; // List of training input values -Network nn; // Neural Network Object -int count; // Total training interations -Landscape land; // Solution space -float theta = 0.0; // Angle of rotation -PFont f; // Font - - -void setup() { - - size(400,400,OPENGL); - - // Create a landscape object - land = new Landscape(20,300,300); - - f = createFont("Courier",12,true); - - nn = new Network(2,4); - - // Create a list of 4 training inputs - inputs = new ArrayList(); - float[] input = new float[2]; - input[0] = 1; - input[1] = 0; - inputs.add((float []) input.clone()); - input[0] = 0; - input[1] = 1; - inputs.add((float []) input.clone()); - input[0] = 1; - input[1] = 1; - inputs.add((float []) input.clone()); - input[0] = 0; - input[1] = 0; - inputs.add((float []) input.clone()); -} - -void draw() { - - int trainingIterationsPerFrame = 5; - - for (int i = 0; i < trainingIterationsPerFrame; i++) { - // Pick a random training input - int pick = int(random(inputs.size())); - // Grab that input - float[] inp = (float[]) inputs.get(pick); - // Compute XOR - float known = 1; - if ((inp[0] == 1.0 && inp[1] == 1.0) || (inp[0] == 0 && inp[1] == 0)) known = 0; - // Train that sucker! - float result = nn.train(inp,known); - count++; - } - - // Ok, visualize the solution space - background(175); - pushMatrix(); - translate(width/2,height/2+20,-160); - rotateX(PI/3); - rotateZ(theta); - - // Put a little BOX on screen - pushMatrix(); - stroke(50); - noFill(); - translate(-10,-10,0); - box(280); - - // Draw the landscape - popMatrix(); - land.calculate(nn); - land.render(); - theta += 0.0025; - popMatrix(); - - // Display overal neural net stats - networkStatus(); - -} - - -void networkStatus() { - float mse = 0.0; - - textFont(f); - fill(0); - text("Your friendly neighborhood neural network solving XOR.",10,20); - text("Total iterations: " + count,10,40); - - for (int i = 0; i < inputs.size(); i++) { - float[] inp = (float[]) inputs.get(i); - float known = 1; - if ((inp[0] == 1.0 && inp[1] == 1.0) || (inp[0] == 0 && inp[1] == 0)) known = 0; - float result = nn.feedForward(inp); - //System.out.println("For: " + inp[0] + " " + inp[1] + ": " + result); - mse += (result - known)*(result - known); - } - - float rmse = sqrt(mse/4.0); - DecimalFormat df = new DecimalFormat("0.000"); - text("Root mean squared error: " + df.format(rmse), 10,60); - -} - - diff --git a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_10_motion101_acceleration/Mover.pde b/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_10_motion101_acceleration/Mover.pde deleted file mode 100644 index e7fc0c200..000000000 --- a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_10_motion101_acceleration/Mover.pde +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Acceleration with Vectors - * by Daniel Shiffman. - * - * Demonstration of the basics of motion with vector. - * A "Mover" object stores location, velocity, and acceleration as vectors - * The motion is controlled by affecting the acceleration (in this case towards the mouse) - */ - - -class Mover { - - // The Mover tracks location, velocity, and acceleration - PVector location; - PVector velocity; - PVector acceleration; - // The Mover's maximum speed - float topspeed; - - Mover() { - // Start in the center - location = new PVector(width/2,height/2); - velocity = new PVector(0,0); - topspeed = 5; - } - - void update() { - - // Compute a vector that points from location to mouse - PVector mouse = new PVector(mouseX,mouseY); - PVector acceleration = PVector.sub(mouse,location); - // Set magnitude of acceleration - //acceleration.setMag(0.2); - acceleration.normalize(); - acceleration.mult(0.2); - - // Velocity changes according to acceleration - velocity.add(acceleration); - // Limit the velocity by topspeed - velocity.limit(topspeed); - // Location changes by velocity - location.add(velocity); - } - - void display() { - stroke(0); - strokeWeight(2); - fill(127); - ellipse(location.x,location.y,48,48); - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_10_motion101_acceleration/_1_10_motion101_acceleration.pde b/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_10_motion101_acceleration/_1_10_motion101_acceleration.pde deleted file mode 100644 index 6822430f0..000000000 --- a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_10_motion101_acceleration/_1_10_motion101_acceleration.pde +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Acceleration with Vectors - * by Daniel Shiffman. - * - * Demonstration of the basics of motion with vector. - * A "Mover" object stores location, velocity, and acceleration as vectors - * The motion is controlled by affecting the acceleration (in this case towards the mouse) - */ - -// A Mover object -Mover mover; - -void setup() { - size(800,200); - smooth(); - mover = new Mover(); -} - -void draw() { - background(255); - - // Update the location - mover.update(); - // Display the Mover - mover.display(); -} - diff --git a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_11_motion101_acceleration_array/Mover.pde b/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_11_motion101_acceleration_array/Mover.pde deleted file mode 100644 index 19114ebf6..000000000 --- a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_11_motion101_acceleration_array/Mover.pde +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Acceleration with Vectors - * by Daniel Shiffman. - * - * Demonstration of the basics of motion with vector. - * A "Mover" object stores location, velocity, and acceleration as vectors - * The motion is controlled by affecting the acceleration (in this case towards the mouse) - */ - - -class Mover { - - // The Mover tracks location, velocity, and acceleration - PVector location; - PVector velocity; - PVector acceleration; - // The Mover's maximum speed - float topspeed; - - Mover() { - // Start in the center - location = new PVector(random(width),random(height)); - velocity = new PVector(0,0); - topspeed = 5; - } - - void update() { - - // Compute a vector that points from location to mouse - PVector mouse = new PVector(mouseX,mouseY); - PVector acceleration = PVector.sub(mouse,location); - // Set magnitude of acceleration - //acceleration.setMag(0.2); - acceleration.normalize(); - acceleration.mult(0.2); - - // Velocity changes according to acceleration - velocity.add(acceleration); - // Limit the velocity by topspeed - velocity.limit(topspeed); - // Location changes by velocity - location.add(velocity); - } - - void display() { - stroke(0); - strokeWeight(2); - fill(127,200); - ellipse(location.x,location.y,48,48); - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_11_motion101_acceleration_array/_1_11_motion101_acceleration_array.pde b/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_11_motion101_acceleration_array/_1_11_motion101_acceleration_array.pde deleted file mode 100644 index b1cafa931..000000000 --- a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_11_motion101_acceleration_array/_1_11_motion101_acceleration_array.pde +++ /dev/null @@ -1,21 +0,0 @@ -Mover[] movers = new Mover[20]; - -void setup() { - size(800,200); - smooth(); - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(); - } -} - -void draw() { - - background(255); - - for (int i = 0; i < movers.length; i++) { - movers[i].update(); - movers[i].display(); - } -} - - diff --git a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_1_bouncingball_novectors/_1_1_bouncingball_novectors.pde b/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_1_bouncingball_novectors/_1_1_bouncingball_novectors.pde deleted file mode 100644 index 6dfb4b6a1..000000000 --- a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_1_bouncingball_novectors/_1_1_bouncingball_novectors.pde +++ /dev/null @@ -1,38 +0,0 @@ -// The Nature of Code -// Daniel Shiffman -// Draft book - -// Example 1-1: Bouncing Ball, no vectors -float x = 100; -float y = 100; -float xspeed = 2.5; -float yspeed = 2; - -void setup() { - size(800, 200); - smooth(); -} - -void draw() { - background(255); - - - // Add the current speed to the location. - x = x + xspeed; - y = y + yspeed; - - if ((x > width) || (x < 0)) { - xspeed = xspeed * -1; - } - if ((y > height) || (y < 0)) { - yspeed = yspeed * -1; - } - - - // Display circle at x location - stroke(0); - strokeWeight(2); - fill(127); - ellipse(x, y, 48, 48); -} - diff --git a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_2_bouncingball_vectors/_1_2_bouncingball_vectors.pde b/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_2_bouncingball_vectors/_1_2_bouncingball_vectors.pde deleted file mode 100644 index 49d7912c2..000000000 --- a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_2_bouncingball_vectors/_1_2_bouncingball_vectors.pde +++ /dev/null @@ -1,38 +0,0 @@ -// The Nature of Code -// Daniel Shiffman -// Draft book - -// Example 1-2: Bouncing Ball, with PVector! -PVector location; -PVector velocity; - -void setup() { - size(200,200); - smooth(); - background(255); - location = new PVector(100,100); - velocity = new PVector(2.5,5); -} - -void draw() { - noStroke(); - fill(255,10); - rect(0,0,width,height); - - // Add the current speed to the location. - location.add(velocity); - - if ((location.x > width) || (location.x < 0)) { - velocity.x = velocity.x * -1; - } - if ((location.y > height) || (location.y < 0)) { - velocity.y = velocity.y * -1; - } - - // Display circle at x location - stroke(0); - fill(175); - ellipse(location.x,location.y,16,16); -} - - diff --git a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_3_vector_subtraction/_1_3_vector_subtraction.pde b/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_3_vector_subtraction/_1_3_vector_subtraction.pde deleted file mode 100644 index b0f89414e..000000000 --- a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_3_vector_subtraction/_1_3_vector_subtraction.pde +++ /dev/null @@ -1,26 +0,0 @@ -// The Nature of Code -// Daniel Shiffman -// Draft book - -// Example 1-3: Vector subtraction - -void setup() { - size(800,200); - smooth(); -} - -void draw() { - background(255); - - PVector mouse = new PVector(mouseX,mouseY); - PVector center = new PVector(width/2,height/2); - mouse.sub(center); - - translate(width/2,height/2); - strokeWeight(2); - stroke(0); - line(0,0,mouse.x,mouse.y); - -} - - diff --git a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_4_vector_multiplication/_1_4_vector_multiplication.pde b/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_4_vector_multiplication/_1_4_vector_multiplication.pde deleted file mode 100644 index fb71aa400..000000000 --- a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_4_vector_multiplication/_1_4_vector_multiplication.pde +++ /dev/null @@ -1,28 +0,0 @@ -// The Nature of Code -// Daniel Shiffman -// Draft book - -// Example 1-4: Vector multiplication - -void setup() { - size(800,200); - smooth(); -} - -void draw() { - background(255); - - PVector mouse = new PVector(mouseX,mouseY); - PVector center = new PVector(width/2,height/2); - mouse.sub(center); - - // Multiplying a vector! The vector is now half its original size (multiplied by 0.5). - mouse.mult(0.5); - - translate(width/2,height/2); - strokeWeight(2); - stroke(0); - line(0,0,mouse.x,mouse.y); -} - - diff --git a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_5_vector_magnitude/_1_5_vector_magnitude.pde b/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_5_vector_magnitude/_1_5_vector_magnitude.pde deleted file mode 100644 index 45a576288..000000000 --- a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_5_vector_magnitude/_1_5_vector_magnitude.pde +++ /dev/null @@ -1,31 +0,0 @@ -// The Nature of Code -// Daniel Shiffman -// Draft book - -// Example 1-5: Vector magnitude - -void setup() { - size(800,200); - smooth(); -} - -void draw() { - background(255); - - PVector mouse = new PVector(mouseX,mouseY); - PVector center = new PVector(width/2,height/2); - mouse.sub(center); - - float m = mouse.mag(); - fill(0); - noStroke(); - rect(0,0,m,10); - - translate(width/2,height/2); - stroke(0); - strokeWeight(2); - line(0,0,mouse.x,mouse.y); - -} - - diff --git a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_6_vector_normalize/_1_6_vector_normalize.pde b/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_6_vector_normalize/_1_6_vector_normalize.pde deleted file mode 100644 index 63ee12326..000000000 --- a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_6_vector_normalize/_1_6_vector_normalize.pde +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Normalize - * by Daniel Shiffman. - * - * Demonstration of normalizing a vector. - * Normalizing a vector sets its length to 1. - */ - -void setup() { - size(800,200); - smooth(); -} - -void draw() { - background(255); - - // A vector that points to the mouse location - PVector mouse = new PVector(mouseX,mouseY); - // A vector that points to the center of the window - PVector center = new PVector(width/2,height/2); - // Subtract center from mouse which results in a vector that points from center to mouse - mouse.sub(center); - - // Normalize the vector - mouse.normalize(); - - // Multiply its length by 50 - mouse.mult(150); - - translate(width/2,height/2); - // Draw the resulting vector - stroke(0); - strokeWeight(2); - line(0,0,mouse.x,mouse.y); - -} - - diff --git a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_7_motion101/Mover.pde b/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_7_motion101/Mover.pde deleted file mode 100644 index 70357ce71..000000000 --- a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_7_motion101/Mover.pde +++ /dev/null @@ -1,39 +0,0 @@ -class Mover { - - PVector location; - PVector velocity; - - Mover() { - location = new PVector(random(width), random(height)); - velocity = new PVector(random(-2, 2), random(-2, 2)); - } - - void update() { - location.add(velocity); - } - - void display() { - stroke(0); - strokeWeight(2); - fill(127); - ellipse(location.x, location.y, 48, 48); - } - - void checkEdges() { - - if (location.x > width) { - location.x = 0; - } - else if (location.x < 0) { - location.x = width; - } - - if (location.y > height) { - location.y = 0; - } - else if (location.y < 0) { - location.y = height; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_7_motion101/_1_7_motion101.pde b/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_7_motion101/_1_7_motion101.pde deleted file mode 100644 index 987429706..000000000 --- a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_7_motion101/_1_7_motion101.pde +++ /dev/null @@ -1,16 +0,0 @@ -Mover mover; - -void setup() { - size(800,200); - smooth(); - mover = new Mover(); -} - -void draw() { - background(255); - - mover.update(); - mover.checkEdges(); - mover.display(); -} - diff --git a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_8_motion101_acceleration/Mover.pde b/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_8_motion101_acceleration/Mover.pde deleted file mode 100644 index 0f815f24a..000000000 --- a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_8_motion101_acceleration/Mover.pde +++ /dev/null @@ -1,45 +0,0 @@ -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float topspeed; - - Mover() { - location = new PVector(width/2, height/2); - velocity = new PVector(0, 0); - acceleration = new PVector(-0.001, 0.01); - topspeed = 10; - } - - void update() { - velocity.add(acceleration); - velocity.limit(topspeed); - location.add(velocity); - } - - void display() { - stroke(0); - strokeWeight(2); - fill(127); - ellipse(location.x, location.y, 48, 48); - } - - void checkEdges() { - - if (location.x > width) { - location.x = 0; - } - else if (location.x < 0) { - location.x = width; - } - - if (location.y > height) { - location.y = 0; - } - else if (location.y < 0) { - location.y = height; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_8_motion101_acceleration/_1_8_motion101_acceleration.pde b/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_8_motion101_acceleration/_1_8_motion101_acceleration.pde deleted file mode 100644 index 34b8281b0..000000000 --- a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_8_motion101_acceleration/_1_8_motion101_acceleration.pde +++ /dev/null @@ -1,17 +0,0 @@ -Mover mover; - -void setup() { - size(800,200); - smooth(); - mover = new Mover(); -} - -void draw() { - background(255); - - mover.update(); - mover.checkEdges(); - mover.display(); -} - - diff --git a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_9_motion101_acceleration/Mover.pde b/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_9_motion101_acceleration/Mover.pde deleted file mode 100644 index 4be6262ee..000000000 --- a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_9_motion101_acceleration/Mover.pde +++ /dev/null @@ -1,49 +0,0 @@ -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float topspeed; - - Mover() { - location = new PVector(width/2, height/2); - velocity = new PVector(0, 0); - topspeed = 6; - } - - void update() { - - acceleration = new PVector(random(-1, 1), random(-1, 1)); - acceleration.normalize(); - acceleration.mult(random(2)); - - velocity.add(acceleration); - velocity.limit(topspeed); - location.add(velocity); - } - - void display() { - stroke(0); - strokeWeight(2); - fill(127); - ellipse(location.x, location.y, 48, 48); - } - - void checkEdges() { - - if (location.x > width) { - location.x = 0; - } - else if (location.x < 0) { - location.x = width; - } - - if (location.y > height) { - location.y = 0; - } - else if (location.y < 0) { - location.y = height; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_9_motion101_acceleration/_1_9_motion101_acceleration.pde b/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_9_motion101_acceleration/_1_9_motion101_acceleration.pde deleted file mode 100644 index e505f1d66..000000000 --- a/java/examples/Books/Nature of Code/chp1_vectors/NOC_1_9_motion101_acceleration/_1_9_motion101_acceleration.pde +++ /dev/null @@ -1,15 +0,0 @@ -Mover mover; - -void setup() { - size(800,200); - smooth(); - mover = new Mover(); -} - -void draw() { - background(255); - mover.update(); - mover.checkEdges(); - mover.display(); -} - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_attractrepel/Attractor.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_attractrepel/Attractor.pde deleted file mode 100644 index d0ce84406..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_attractrepel/Attractor.pde +++ /dev/null @@ -1,74 +0,0 @@ -// Attraction -// Daniel Shiffman - -// A class for a draggable attractive body in our world - -class Attractor { - float mass; // Mass, tied to size - PVector location; // Location - boolean dragging = false; // Is the object being dragged? - boolean rollover = false; // Is the mouse over the ellipse? - PVector drag; // holds the offset for when object is clicked on - - Attractor() { - location = new PVector(width/2,height/2); - mass = 10; - drag = new PVector(0.0,0.0); - } - - PVector attract(Mover m) { - PVector force = PVector.sub(location,m.location); // Calculate direction of force - float d = force.mag(); // Distance between objects - d = constrain(d,5.0,25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects - force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction) - float strength = (g * mass * m.mass) / (d * d); // Calculate gravitional force magnitude - force.mult(strength); // Get force vector --> magnitude * direction - return force; - } - - // Method to display - void display() { - ellipseMode(CENTER); - stroke(0); - if (dragging) fill (50); - else if (rollover) fill(100); - else fill(0); - ellipse(location.x,location.y,mass*6,mass*6); - } - - // The methods below are for mouse interaction - void clicked(int mx, int my) { - float d = dist(mx,my,location.x,location.y); - if (d < mass) { - dragging = true; - drag.x = location.x-mx; - drag.y = location.y-my; - } - } - - void rollover(int mx, int my) { - float d = dist(mx,my,location.x,location.y); - if (d < mass) { - rollover = true; - } - else { - rollover = false; - } - } - - void stopDragging() { - dragging = false; - } - - - - void drag() { - if (dragging) { - location.x = mouseX + drag.x; - location.y = mouseY + drag.y; - } - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_attractrepel/Mover.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_attractrepel/Mover.pde deleted file mode 100644 index 8b2214570..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_attractrepel/Mover.pde +++ /dev/null @@ -1,69 +0,0 @@ -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float mass; - - Mover(float m, float x , float y) { - mass = m; - location = new PVector(x,y); - velocity = new PVector(0,0); - acceleration = new PVector(0,0); - } - - void applyForce(PVector force) { - PVector f = PVector.div(force,mass); - acceleration.add(f); - } - - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - } - - void display() { - stroke(0); - fill(175,200); - ellipse(location.x,location.y,mass*2,mass*2); - } - - PVector repel(Mover m) { - PVector force = PVector.sub(location,m.location); // Calculate direction of force - float distance = force.mag(); // Distance between objects - distance = constrain(distance,1.0,10000.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects - force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction - - float strength = (g * mass * m.mass) / (distance * distance); // Calculate gravitional force magnitude - force.mult(-1*strength); // Get force vector --> magnitude * direction - return force; - } - - void checkEdges() { - - if (location.x > width) { - location.x = width; - velocity.x *= -1; - } - else if (location.x < 0) { - location.x = 0; - velocity.x *= -1; - } - - if (location.y > height) { - location.y = height; - velocity.y *= -1; - } - else if (location.y < 0) { - location.y = 0; - velocity.y *= -1; - } - - } - -} - - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_attractrepel/_02forces_attractrepel.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_attractrepel/_02forces_attractrepel.pde deleted file mode 100644 index 1a4c37a61..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_attractrepel/_02forces_attractrepel.pde +++ /dev/null @@ -1,52 +0,0 @@ -Mover[] movers = new Mover[20]; - -Attractor a; - -float g = 1; - -void setup() { - size(800,200); - smooth(); - a = new Attractor(); - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(random(4,12),random(width),random(height)); - } -} - -void draw() { - background(255); - - a.display(); - - - for (int i = 0; i < movers.length; i++) { - for (int j = 0; j < movers.length; j++) { - if (i != j) { - PVector force = movers[j].repel(movers[i]); - movers[i].applyForce(force); - } - } - - PVector force = a.attract(movers[i]); - movers[i].applyForce(force); - movers[i].update(); - movers[i].display(); - } - - - -} - - - - - - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_attraction_3D/Attractor.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_attraction_3D/Attractor.pde deleted file mode 100644 index 36b144ae3..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_attraction_3D/Attractor.pde +++ /dev/null @@ -1,39 +0,0 @@ -// Attraction -// Daniel Shiffman - -// A class for a draggable attractive body in our world - -class Attractor { - float mass; // Mass, tied to size - PVector location; // Location - float g; - - Attractor() { - location = new PVector(0,0); - mass = 20; - g = 0.4; - } - - - PVector attract(Mover m) { - PVector force = PVector.sub(location,m.location); // Calculate direction of force - float distance = force.mag(); // Distance between objects - distance = constrain(distance,5.0,25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects - force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction) - float strength = (g * mass * m.mass) / (distance * distance); // Calculate gravitional force magnitude - force.mult(strength); // Get force vector --> magnitude * direction - return force; - } - - // Method to display - void display() { - stroke(255); - noFill(); - pushMatrix(); - translate(location.x,location.y,location.z); - sphere(mass*2); - popMatrix(); - } -} - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_attraction_3D/Mover.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_attraction_3D/Mover.pde deleted file mode 100644 index 5c9c79ea3..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_attraction_3D/Mover.pde +++ /dev/null @@ -1,51 +0,0 @@ -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float mass; - - Mover(float m, float x, float y, float z) { - mass = m; - location = new PVector(x,y,z); - velocity = new PVector(1,0); - acceleration = new PVector(0,0); - } - - void applyForce(PVector force) { - PVector f = PVector.div(force,mass); - acceleration.add(f); - } - - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - } - - void display() { - noStroke(); - fill(255); - pushMatrix(); - translate(location.x,location.y,location.z); - sphere(mass*8); - popMatrix(); - } - - void checkEdges() { - - if (location.x > width) { - location.x = 0; - } - else if (location.x < 0) { - location.x = width; - } - - if (location.y > height) { - velocity.y *= -1; - location.y = height; - } - } -} - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_attraction_3D/_02forces_many_attraction_3D.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_attraction_3D/_02forces_many_attraction_3D.pde deleted file mode 100644 index e88b686c2..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_attraction_3D/_02forces_many_attraction_3D.pde +++ /dev/null @@ -1,50 +0,0 @@ -import processing.opengl.*; - -Mover[] movers = new Mover[10]; - -Attractor a; - -float angle = 0; - -void setup() { - size(800,200,OPENGL); - smooth(); - background(255); - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(random(0.1,2),random(-width/2,width/2),random(-height/2,height/2),random(-100,100)); - } - a = new Attractor(); -} - -void draw() { - background(0); - sphereDetail(8); - lights(); - translate(width/2,height/2); - rotateY(angle); - - - a.display(); - - for (int i = 0; i < movers.length; i++) { - PVector force = a.attract(movers[i]); - movers[i].applyForce(force); - - movers[i].update(); - movers[i].display(); - } - - angle += 0.003; - -} - - - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_attraction_3D/sketch.properties b/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_attraction_3D/sketch.properties deleted file mode 100644 index 28faa5897..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_attraction_3D/sketch.properties +++ /dev/null @@ -1 +0,0 @@ -mode=Standard diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/Mover.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/Mover.pde deleted file mode 100644 index b092ef546..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/Mover.pde +++ /dev/null @@ -1,70 +0,0 @@ -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float mass; - - Mover(float m, float x, float y) { - mass = m; - location = new PVector(x, y); - velocity = new PVector(0, 0); - acceleration = new PVector(0, 0); - } - - void applyForce(PVector force) { - PVector f = PVector.div(force, mass); - acceleration.add(f); - } - - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - } - - void display() { - stroke(0); - fill(175, 200); - ellipse(location.x, location.y, mass*16, mass*16); - } - - PVector attract(Mover m) { - PVector force = PVector.sub(location, m.location); // Calculate direction of force - float distance = force.mag(); // Distance between objects - distance = constrain(distance, 5.0, 25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects - force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction - - float strength = (g * mass * m.mass) / (distance * distance); // Calculate gravitional force magnitude - force.mult(strength); // Get force vector --> magnitude * direction - return force; - } - - void boundaries() { - - float d = 50; - - PVector force = new PVector(0, 0); - - if (location.x < d) { - force.x = 1; - } - else if (location.x > width -d) { - force.x = -1; - } - - if (location.y < d) { - force.y = 1; - } - else if (location.y > height-d) { - force.y = -1; - } - - force.normalize(); - force.mult(0.1); - - applyForce(force); - } -} - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/_02forces_many_mutual_boundaries.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/_02forces_many_mutual_boundaries.pde deleted file mode 100644 index 3ccfbe320..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/_02forces_many_mutual_boundaries.pde +++ /dev/null @@ -1,44 +0,0 @@ -Mover[] movers = new Mover[20]; - -float g = 0.4; - -void setup() { - size(800,200); - smooth(); - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(random(1,2),random(width),random(height)); - } -} - -void draw() { - background(255); - - - for (int i = 0; i < movers.length; i++) { - for (int j = 0; j < movers.length; j++) { - if (i != j) { - PVector force = movers[j].attract(movers[i]); - movers[i].applyForce(force); - } - } - - movers[i].boundaries(); - - movers[i].update(); - movers[i].display(); - } - -} - - - - - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/sketch.properties b/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/sketch.properties deleted file mode 100644 index 6d28cd598..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/sketch.properties +++ /dev/null @@ -1 +0,0 @@ -mode=JavaScript diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/web-export/_02forces_many_mutual_boundaries.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/web-export/_02forces_many_mutual_boundaries.pde deleted file mode 100644 index 6b67a403b..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/web-export/_02forces_many_mutual_boundaries.pde +++ /dev/null @@ -1,115 +0,0 @@ -Mover[] movers = new Mover[20]; - -float g = 0.4; - -void setup() { - size(800,200); - smooth(); - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(random(1,2),random(width),random(height)); - } -} - -void draw() { - background(255); - - - for (int i = 0; i < movers.length; i++) { - for (int j = 0; j < movers.length; j++) { - if (i != j) { - PVector force = movers[j].attract(movers[i]); - movers[i].applyForce(force); - } - } - - movers[i].boundaries(); - - movers[i].update(); - movers[i].display(); - } - -} - - - - - - - - - - - - - -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float mass; - - Mover(float m, float x, float y) { - mass = m; - location = new PVector(x, y); - velocity = new PVector(0, 0); - acceleration = new PVector(0, 0); - } - - void applyForce(PVector force) { - PVector f = PVector.div(force, mass); - acceleration.add(f); - } - - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - } - - void display() { - stroke(0); - fill(175, 200); - ellipse(location.x, location.y, mass*16, mass*16); - } - - PVector attract(Mover m) { - PVector force = PVector.sub(location, m.location); // Calculate direction of force - float distance = force.mag(); // Distance between objects - distance = constrain(distance, 5.0, 25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects - force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction - - float strength = (g * mass * m.mass) / (distance * distance); // Calculate gravitional force magnitude - force.mult(strength); // Get force vector --> magnitude * direction - return force; - } - - void boundaries() { - - float d = 50; - - PVector force = new PVector(0, 0); - - if (location.x < d) { - force.x = 1; - } - else if (location.x > width -d) { - force.x = -1; - } - - if (location.y < d) { - force.y = 1; - } - else if (location.y > height-d) { - force.y = -1; - } - - force.normalize(); - force.mult(0.1); - - applyForce(force); - } -} - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/web-export/processing.js b/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/web-export/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_02forces_many_mutual_boundaries/web-export/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_1_forces/Mover.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_1_forces/Mover.pde deleted file mode 100644 index 2e13412b5..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_1_forces/Mover.pde +++ /dev/null @@ -1,53 +0,0 @@ -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float mass; - - Mover() { - location = new PVector(30,30); - velocity = new PVector(0,0); - acceleration = new PVector(0,0); - mass = 1; - } - - void applyForce(PVector force) { - PVector f = PVector.div(force,mass); - acceleration.add(f); - } - - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - } - - void display() { - stroke(0); - strokeWeight(2); - fill(127); - ellipse(location.x,location.y,48,48); - } - - void checkEdges() { - - if (location.x > width) { - location.x = width; - velocity.x *= -1; - } else if (location.x < 0) { - velocity.x *= -1; - location.x = 0; - } - - if (location.y > height) { - velocity.y *= -1; - location.y = height; - } - - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_1_forces/_2_1_forces.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_1_forces/_2_1_forces.pde deleted file mode 100644 index c87fd78e7..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_1_forces/_2_1_forces.pde +++ /dev/null @@ -1,27 +0,0 @@ -Mover m; - -void setup() { - size(800,200); - smooth(); - m = new Mover(); -} - -void draw() { - background(255); - - PVector wind = new PVector(0.01,0); - PVector gravity = new PVector(0,0.1); - m.applyForce(wind); - m.applyForce(gravity); - - - m.update(); - m.display(); - m.checkEdges(); - -} - - - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_2_forces_many/Mover.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_2_forces_many/Mover.pde deleted file mode 100644 index 02f1804bb..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_2_forces_many/Mover.pde +++ /dev/null @@ -1,53 +0,0 @@ -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float mass; - - Mover(float m, float x , float y) { - mass = m; - location = new PVector(x,y); - velocity = new PVector(0,0); - acceleration = new PVector(0,0); - } - - void applyForce(PVector force) { - PVector f = PVector.div(force,mass); - acceleration.add(f); - } - - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - } - - void display() { - stroke(0); - strokeWeight(2); - fill(0,127); - ellipse(location.x,location.y,mass*16,mass*16); - } - - void checkEdges() { - - if (location.x > width) { - location.x = width; - velocity.x *= -1; - } else if (location.x < 0) { - velocity.x *= -1; - location.x = 0; - } - - if (location.y > height) { - velocity.y *= -1; - location.y = height; - } - - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_2_forces_many/_2_2_forces_many.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_2_forces_many/_2_2_forces_many.pde deleted file mode 100644 index bf22b65af..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_2_forces_many/_2_2_forces_many.pde +++ /dev/null @@ -1,36 +0,0 @@ -Mover[] movers = new Mover[20]; - -void setup() { - size(800,200); - smooth(); - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(random(0.1,4),0,0); - } -} - -void draw() { - background(255); - - for (int i = 0; i < movers.length; i++) { - - PVector wind = new PVector(0.01,0); - PVector gravity = new PVector(0,0.1); - - movers[i].applyForce(wind); - movers[i].applyForce(gravity); - - movers[i].update(); - movers[i].display(); - movers[i].checkEdges(); - } - -} - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_3_forces_many_realgravity/Mover.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_3_forces_many_realgravity/Mover.pde deleted file mode 100644 index 02f1804bb..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_3_forces_many_realgravity/Mover.pde +++ /dev/null @@ -1,53 +0,0 @@ -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float mass; - - Mover(float m, float x , float y) { - mass = m; - location = new PVector(x,y); - velocity = new PVector(0,0); - acceleration = new PVector(0,0); - } - - void applyForce(PVector force) { - PVector f = PVector.div(force,mass); - acceleration.add(f); - } - - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - } - - void display() { - stroke(0); - strokeWeight(2); - fill(0,127); - ellipse(location.x,location.y,mass*16,mass*16); - } - - void checkEdges() { - - if (location.x > width) { - location.x = width; - velocity.x *= -1; - } else if (location.x < 0) { - velocity.x *= -1; - location.x = 0; - } - - if (location.y > height) { - velocity.y *= -1; - location.y = height; - } - - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_3_forces_many_realgravity/_2_3_forces_many_realgravity.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_3_forces_many_realgravity/_2_3_forces_many_realgravity.pde deleted file mode 100644 index 377b98f02..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_3_forces_many_realgravity/_2_3_forces_many_realgravity.pde +++ /dev/null @@ -1,34 +0,0 @@ -Mover[] movers = new Mover[20]; - -void setup() { - size(800, 200); - smooth(); - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(random(1, 4), 0, 0); - } -} - -void draw() { - background(255); - - for (int i = 0; i < movers.length; i++) { - - PVector wind = new PVector(0.01, 0); - PVector gravity = new PVector(0, 0.1*movers[i].mass); - - movers[i].applyForce(wind); - movers[i].applyForce(gravity); - - movers[i].update(); - movers[i].display(); - movers[i].checkEdges(); - } -} - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_4_forces_friction/Mover.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_4_forces_friction/Mover.pde deleted file mode 100644 index 7fb1353b5..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_4_forces_friction/Mover.pde +++ /dev/null @@ -1,53 +0,0 @@ -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float mass; - - Mover(float m, float x , float y) { - mass = m; - location = new PVector(x,y); - velocity = new PVector(0,0); - acceleration = new PVector(0,0); - } - - void applyForce(PVector force) { - PVector f = PVector.div(force,mass); - acceleration.add(f); - } - - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - } - - void display() { - stroke(0); - strokeWeight(2); - fill(0,127); - ellipse(location.x,location.y,mass*16,mass*16); - } - - void checkEdges() { - - if (location.x > width) { - location.x = width; - velocity.x *= -1; - } else if (location.x < 0) { - location.x = 0; - velocity.x *= -1; - } - - if (location.y > height) { - velocity.y *= -1; - location.y = height; - } - - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_4_forces_friction/_2_4_forces_friction.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_4_forces_friction/_2_4_forces_friction.pde deleted file mode 100644 index fccf7341c..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_4_forces_friction/_2_4_forces_friction.pde +++ /dev/null @@ -1,42 +0,0 @@ -Mover[] movers = new Mover[5]; - -void setup() { - size(383, 200); - randomSeed(1); - smooth(); - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(random(1, 4), random(width), 0); - } -} - -void draw() { - background(255); - - for (int i = 0; i < movers.length; i++) { - - PVector wind = new PVector(0.01, 0); - PVector gravity = new PVector(0, 0.1*movers[i].mass); - - float c = 0.05; - PVector friction = movers[i].velocity.get(); - friction.mult(-1); - friction.normalize(); - friction.mult(c); - - movers[i].applyForce(friction); - movers[i].applyForce(wind); - movers[i].applyForce(gravity); - - movers[i].update(); - movers[i].display(); - movers[i].checkEdges(); - } -} - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_4_forces_nofriction/Mover.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_4_forces_nofriction/Mover.pde deleted file mode 100644 index 7fb1353b5..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_4_forces_nofriction/Mover.pde +++ /dev/null @@ -1,53 +0,0 @@ -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float mass; - - Mover(float m, float x , float y) { - mass = m; - location = new PVector(x,y); - velocity = new PVector(0,0); - acceleration = new PVector(0,0); - } - - void applyForce(PVector force) { - PVector f = PVector.div(force,mass); - acceleration.add(f); - } - - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - } - - void display() { - stroke(0); - strokeWeight(2); - fill(0,127); - ellipse(location.x,location.y,mass*16,mass*16); - } - - void checkEdges() { - - if (location.x > width) { - location.x = width; - velocity.x *= -1; - } else if (location.x < 0) { - location.x = 0; - velocity.x *= -1; - } - - if (location.y > height) { - velocity.y *= -1; - location.y = height; - } - - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_4_forces_nofriction/_2_4_forces_nofriction.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_4_forces_nofriction/_2_4_forces_nofriction.pde deleted file mode 100644 index 23f0304e2..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_4_forces_nofriction/_2_4_forces_nofriction.pde +++ /dev/null @@ -1,42 +0,0 @@ -Mover[] movers = new Mover[5]; - -void setup() { - size(383, 200); - randomSeed(1); - smooth(); - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(random(1, 4), random(width), 0); - } -} - -void draw() { - background(255); - - for (int i = 0; i < movers.length; i++) { - - PVector wind = new PVector(0.01, 0); - PVector gravity = new PVector(0, 0.1*movers[i].mass); - - float c = 0.05; - PVector friction = movers[i].velocity.get(); - friction.mult(-1); - friction.normalize(); - friction.mult(c); - - //movers[i].applyForce(friction); - movers[i].applyForce(wind); - movers[i].applyForce(gravity); - - movers[i].update(); - movers[i].display(); - movers[i].checkEdges(); - } -} - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/Liquid.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/Liquid.pde deleted file mode 100644 index ab0e3ee2d..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/Liquid.pde +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Forces (Gravity and Fluid Resistence) with Vectors - * by Daniel Shiffman. - * - * Demonstration of multiple force acting on bodies (Mover class) - * Bodies experience gravity continuously - * Bodies experience fluid resistance when in "water" - */ - - // Liquid class - class Liquid { - - - // Liquid is a rectangle - float x,y,w,h; - // Coefficient of drag - float c; - - Liquid(float x_, float y_, float w_, float h_, float c_) { - x = x_; - y = y_; - w = w_; - h = h_; - c = c_; - } - - // Is the Mover in the Liquid? - boolean contains(Mover m) { - PVector l = m.location; - if (l.x > x && l.x < x + w && l.y > y && l.y < y + h) { - return true; - } - else { - return false; - } - } - - // Calculate drag force - PVector drag(Mover m) { - // Magnitude is coefficient * speed squared - float speed = m.velocity.mag(); - float dragMagnitude = c * speed * speed; - - // Direction is inverse of velocity - PVector dragForce = m.velocity.get(); - dragForce.mult(-1); - - // Scale according to magnitude - // dragForce.setMag(dragMagnitude); - dragForce.normalize(); - dragForce.mult(dragMagnitude); - return dragForce; - } - - void display() { - noStroke(); - fill(50); - rect(x,y,w,h); - } - -} - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/Mover.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/Mover.pde deleted file mode 100644 index eaad60a81..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/Mover.pde +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Forces (Gravity and Fluid Resistence) with Vectors - * by Daniel Shiffman. - * - * Demonstration of multiple force acting on bodies (Mover class) - * Bodies experience gravity continuously - * Bodies experience fluid resistance when in "water" - */ - - -class Mover { - - // location, velocity, and acceleration - PVector location; - PVector velocity; - PVector acceleration; - - // Mass is tied to size - float mass; - - Mover(float m, float x, float y) { - mass = m; - location = new PVector(x, y); - velocity = new PVector(0, 0); - acceleration = new PVector(0, 0); - } - - // Newton's 2nd law: F = M * A - // or A = F / M - void applyForce(PVector force) { - // Divide by mass - PVector f = PVector.div(force, mass); - // Accumulate all forces in acceleration - acceleration.add(f); - } - - void update() { - - // Velocity changes according to acceleration - velocity.add(acceleration); - // Location changes by velocity - location.add(velocity); - // We must clear acceleration each frame - acceleration.mult(0); - } - - // Draw Mover - void display() { - stroke(0); - strokeWeight(2); - fill(127, 200); - ellipse(location.x, location.y, mass*16, mass*16); - } - - // Bounce off bottom of window - void checkEdges() { - if (location.y > height) { - velocity.y *= -0.9; // A little dampening when hitting the bottom - location.y = height; - } - } -} - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/_2_5_fluidresistance.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/_2_5_fluidresistance.pde deleted file mode 100644 index d1a2201c4..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/_2_5_fluidresistance.pde +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Forces (Gravity and Fluid Resistence) with Vectors - * by Daniel Shiffman. - * - * Demonstration of multiple force acting on bodies (Mover class) - * Bodies experience gravity continuously - * Bodies experience fluid resistance when in "water" - */ - -// Five moving bodies -Mover[] movers = new Mover[11]; - -// Liquid -Liquid liquid; - -void setup() { - size(800, 200); - smooth(); - reset(); - // Create liquid object - liquid = new Liquid(0, height/2, width, height/2, 0.1); -} - -void draw() { - background(255); - - // Draw water - liquid.display(); - - for (int i = 0; i < movers.length; i++) { - - // Is the Mover in the liquid? - if (liquid.contains(movers[i])) { - // Calculate drag force - PVector dragForce = liquid.drag(movers[i]); - // Apply drag force to Mover - movers[i].applyForce(dragForce); - } - - // Gravity is scaled by mass here! - PVector gravity = new PVector(0, 0.1*movers[i].mass); - // Apply gravity - movers[i].applyForce(gravity); - - // Update and display - movers[i].update(); - movers[i].display(); - movers[i].checkEdges(); - } - - fill(0); - text("click mouse to reset",10,30); - -} - -void mousePressed() { - reset(); -} - -// Restart all the Mover objects randomly -void reset() { - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(random(0.5, 3), 40+i*70, 0); - } -} - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/sketch.properties b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/sketch.properties deleted file mode 100644 index 28faa5897..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/sketch.properties +++ /dev/null @@ -1 +0,0 @@ -mode=Standard diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/web-export/_2_5_fluidresistance.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/web-export/_2_5_fluidresistance.pde deleted file mode 100644 index 4c10779db..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/web-export/_2_5_fluidresistance.pde +++ /dev/null @@ -1,199 +0,0 @@ -/** - * Forces (Gravity and Fluid Resistence) with Vectors - * by Daniel Shiffman. - * - * Demonstration of multiple force acting on bodies (Mover class) - * Bodies experience gravity continuously - * Bodies experience fluid resistance when in "water" - */ - -// Five moving bodies -Mover[] movers = new Mover[11]; - -// Liquid -Liquid liquid; - -void setup() { - size(800, 360); - smooth(); - reset(); - // Create liquid object - liquid = new Liquid(0, height/2, width, height/2, 0.1); -} - -void draw() { - background(0); - - // Draw water - liquid.display(); - - for (int i = 0; i < movers.length; i++) { - - // Is the Mover in the liquid? - if (liquid.contains(movers[i])) { - // Calculate drag force - PVector dragForce = liquid.drag(movers[i]); - // Apply drag force to Mover - movers[i].applyForce(dragForce); - } - - // Gravity is scaled by mass here! - PVector gravity = new PVector(0, 0.1*movers[i].mass); - // Apply gravity - movers[i].applyForce(gravity); - - // Update and display - movers[i].update(); - movers[i].display(); - movers[i].checkEdges(); - } - - fill(255); - text("click mouse to reset",10,30); - -} - -void mousePressed() { - reset(); -} - -// Restart all the Mover objects randomly -void reset() { - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(random(1, 5), 40+i*70, 0); - } -} - - - - - - - -/** - * Forces (Gravity and Fluid Resistence) with Vectors - * by Daniel Shiffman. - * - * Demonstration of multiple force acting on bodies (Mover class) - * Bodies experience gravity continuously - * Bodies experience fluid resistance when in "water" - */ - - // Liquid class - class Liquid { - - - // Liquid is a rectangle - float x,y,w,h; - // Coefficient of drag - float c; - - Liquid(float x_, float y_, float w_, float h_, float c_) { - x = x_; - y = y_; - w = w_; - h = h_; - c = c_; - } - - // Is the Mover in the Liquid? - boolean contains(Mover m) { - PVector l = m.location; - if (l.x > x && l.x < x + w && l.y > y && l.y < y + h) { - return true; - } - else { - return false; - } - } - - // Calculate drag force - PVector drag(Mover m) { - // Magnitude is coefficient * speed squared - float speed = m.velocity.mag(); - float dragMagnitude = c * speed * speed; - - // Direction is inverse of velocity - PVector dragForce = m.velocity.get(); - dragForce.mult(-1); - - // Scale according to magnitude - // dragForce.setMag(dragMagnitude); - dragForce.normalize(); - dragForce.mult(dragMagnitude); - return dragForce; - } - - void display() { - noStroke(); - fill(127); - rect(x,y,w,h); - } - -} - -/** - * Forces (Gravity and Fluid Resistence) with Vectors - * by Daniel Shiffman. - * - * Demonstration of multiple force acting on bodies (Mover class) - * Bodies experience gravity continuously - * Bodies experience fluid resistance when in "water" - */ - - -class Mover { - - // location, velocity, and acceleration - PVector location; - PVector velocity; - PVector acceleration; - - // Mass is tied to size - float mass; - - Mover(float m, float x, float y) { - mass = m; - location = new PVector(x, y); - velocity = new PVector(0, 0); - acceleration = new PVector(0, 0); - } - - // Newton's 2nd law: F = M * A - // or A = F / M - void applyForce(PVector force) { - // Divide by mass - PVector f = PVector.div(force, mass); - // Accumulate all forces in acceleration - acceleration.add(f); - } - - void update() { - - // Velocity changes according to acceleration - velocity.add(acceleration); - // Location changes by velocity - location.add(velocity); - // We must clear acceleration each frame - acceleration.mult(0); - } - - // Draw Mover - void display() { - stroke(255); - strokeWeight(2); - fill(255, 200); - ellipse(location.x, location.y, mass*16, mass*16); - } - - // Bounce off bottom of window - void checkEdges() { - if (location.y > height) { - velocity.y *= -0.9; // A little dampening when hitting the bottom - location.y = height; - } - } -} - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/web-export/processing.js b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/web-export/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance/web-export/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/Liquid.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/Liquid.pde deleted file mode 100644 index ab0e3ee2d..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/Liquid.pde +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Forces (Gravity and Fluid Resistence) with Vectors - * by Daniel Shiffman. - * - * Demonstration of multiple force acting on bodies (Mover class) - * Bodies experience gravity continuously - * Bodies experience fluid resistance when in "water" - */ - - // Liquid class - class Liquid { - - - // Liquid is a rectangle - float x,y,w,h; - // Coefficient of drag - float c; - - Liquid(float x_, float y_, float w_, float h_, float c_) { - x = x_; - y = y_; - w = w_; - h = h_; - c = c_; - } - - // Is the Mover in the Liquid? - boolean contains(Mover m) { - PVector l = m.location; - if (l.x > x && l.x < x + w && l.y > y && l.y < y + h) { - return true; - } - else { - return false; - } - } - - // Calculate drag force - PVector drag(Mover m) { - // Magnitude is coefficient * speed squared - float speed = m.velocity.mag(); - float dragMagnitude = c * speed * speed; - - // Direction is inverse of velocity - PVector dragForce = m.velocity.get(); - dragForce.mult(-1); - - // Scale according to magnitude - // dragForce.setMag(dragMagnitude); - dragForce.normalize(); - dragForce.mult(dragMagnitude); - return dragForce; - } - - void display() { - noStroke(); - fill(50); - rect(x,y,w,h); - } - -} - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/Mover.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/Mover.pde deleted file mode 100644 index 5500dc39d..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/Mover.pde +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Forces (Gravity and Fluid Resistence) with Vectors - * by Daniel Shiffman. - * - * Demonstration of multiple force acting on bodies (Mover class) - * Bodies experience gravity continuously - * Bodies experience fluid resistance when in "water" - */ - - -class Mover { - - // location, velocity, and acceleration - PVector location; - PVector velocity; - PVector acceleration; - - // Mass is tied to size - float mass; - - Mover(float m, float x, float y) { - mass = m; - location = new PVector(x, y); - velocity = new PVector(0, 0); - acceleration = new PVector(0, 0); - } - - // Newton's 2nd law: F = M * A - // or A = F / M - void applyForce(PVector force) { - // Divide by mass - PVector f = PVector.div(force, mass); - // Accumulate all forces in acceleration - acceleration.add(f); - } - - void update() { - - // Velocity changes according to acceleration - velocity.add(acceleration); - // Location changes by velocity - location.add(velocity); - // We must clear acceleration each frame - acceleration.mult(0); - } - - // Draw Mover - void display() { - stroke(0); - strokeWeight(2*2.25); - fill(127,200); - ellipse(location.x, location.y, mass*16, mass*16); - } - - // Bounce off bottom of window - void checkEdges() { - if (location.y > height) { - velocity.y *= -0.9; // A little dampening when hitting the bottom - location.y = height; - } - } -} - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/_2_5_fluidresistance_sequence.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/_2_5_fluidresistance_sequence.pde deleted file mode 100644 index aa712c059..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/_2_5_fluidresistance_sequence.pde +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Forces (Gravity and Fluid Resistence) with Vectors - * by Daniel Shiffman. - * - * Demonstration of multiple force acting on bodies (Mover class) - * Bodies experience gravity continuously - * Bodies experience fluid resistance when in "water" - */ - -// Five moving bodies -Mover[] movers = new Mover[5]; - -// Liquid -Liquid liquid; - -void setup() { - size(450, 450); - smooth(); - randomSeed(1); - reset(); - // Create liquid object - liquid = new Liquid(0, height/2, width, height/2, 0.1); -} - -void draw() { - background(255); - - // Draw water - liquid.display(); - - for (int i = 0; i < movers.length; i++) { - - // Is the Mover in the liquid? - if (liquid.contains(movers[i])) { - // Calculate drag force - PVector dragForce = liquid.drag(movers[i]); - // Apply drag force to Mover - movers[i].applyForce(dragForce); - } - - // Gravity is scaled by mass here! - PVector gravity = new PVector(0, 0.1*movers[i].mass); - // Apply gravity - movers[i].applyForce(gravity); - - // Update and display - movers[i].update(); - movers[i].display(); - movers[i].checkEdges(); - } - - fill(255); - //text("click mouse to reset",10,30); - - if (frameCount % 20 == 0) saveFrame("ch2_05_####.png"); -} - -void mousePressed() { - reset(); -} - -// Restart all the Mover objects randomly -void reset() { - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(random(0.5*2.25,3*2.25), 20*2.25+i*40*2.25, 0); - } -} - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/sketch.properties b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/sketch.properties deleted file mode 100644 index 28faa5897..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/sketch.properties +++ /dev/null @@ -1 +0,0 @@ -mode=Standard diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/web-export/_2_5_fluidresistance.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/web-export/_2_5_fluidresistance.pde deleted file mode 100644 index 4c10779db..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/web-export/_2_5_fluidresistance.pde +++ /dev/null @@ -1,199 +0,0 @@ -/** - * Forces (Gravity and Fluid Resistence) with Vectors - * by Daniel Shiffman. - * - * Demonstration of multiple force acting on bodies (Mover class) - * Bodies experience gravity continuously - * Bodies experience fluid resistance when in "water" - */ - -// Five moving bodies -Mover[] movers = new Mover[11]; - -// Liquid -Liquid liquid; - -void setup() { - size(800, 360); - smooth(); - reset(); - // Create liquid object - liquid = new Liquid(0, height/2, width, height/2, 0.1); -} - -void draw() { - background(0); - - // Draw water - liquid.display(); - - for (int i = 0; i < movers.length; i++) { - - // Is the Mover in the liquid? - if (liquid.contains(movers[i])) { - // Calculate drag force - PVector dragForce = liquid.drag(movers[i]); - // Apply drag force to Mover - movers[i].applyForce(dragForce); - } - - // Gravity is scaled by mass here! - PVector gravity = new PVector(0, 0.1*movers[i].mass); - // Apply gravity - movers[i].applyForce(gravity); - - // Update and display - movers[i].update(); - movers[i].display(); - movers[i].checkEdges(); - } - - fill(255); - text("click mouse to reset",10,30); - -} - -void mousePressed() { - reset(); -} - -// Restart all the Mover objects randomly -void reset() { - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(random(1, 5), 40+i*70, 0); - } -} - - - - - - - -/** - * Forces (Gravity and Fluid Resistence) with Vectors - * by Daniel Shiffman. - * - * Demonstration of multiple force acting on bodies (Mover class) - * Bodies experience gravity continuously - * Bodies experience fluid resistance when in "water" - */ - - // Liquid class - class Liquid { - - - // Liquid is a rectangle - float x,y,w,h; - // Coefficient of drag - float c; - - Liquid(float x_, float y_, float w_, float h_, float c_) { - x = x_; - y = y_; - w = w_; - h = h_; - c = c_; - } - - // Is the Mover in the Liquid? - boolean contains(Mover m) { - PVector l = m.location; - if (l.x > x && l.x < x + w && l.y > y && l.y < y + h) { - return true; - } - else { - return false; - } - } - - // Calculate drag force - PVector drag(Mover m) { - // Magnitude is coefficient * speed squared - float speed = m.velocity.mag(); - float dragMagnitude = c * speed * speed; - - // Direction is inverse of velocity - PVector dragForce = m.velocity.get(); - dragForce.mult(-1); - - // Scale according to magnitude - // dragForce.setMag(dragMagnitude); - dragForce.normalize(); - dragForce.mult(dragMagnitude); - return dragForce; - } - - void display() { - noStroke(); - fill(127); - rect(x,y,w,h); - } - -} - -/** - * Forces (Gravity and Fluid Resistence) with Vectors - * by Daniel Shiffman. - * - * Demonstration of multiple force acting on bodies (Mover class) - * Bodies experience gravity continuously - * Bodies experience fluid resistance when in "water" - */ - - -class Mover { - - // location, velocity, and acceleration - PVector location; - PVector velocity; - PVector acceleration; - - // Mass is tied to size - float mass; - - Mover(float m, float x, float y) { - mass = m; - location = new PVector(x, y); - velocity = new PVector(0, 0); - acceleration = new PVector(0, 0); - } - - // Newton's 2nd law: F = M * A - // or A = F / M - void applyForce(PVector force) { - // Divide by mass - PVector f = PVector.div(force, mass); - // Accumulate all forces in acceleration - acceleration.add(f); - } - - void update() { - - // Velocity changes according to acceleration - velocity.add(acceleration); - // Location changes by velocity - location.add(velocity); - // We must clear acceleration each frame - acceleration.mult(0); - } - - // Draw Mover - void display() { - stroke(255); - strokeWeight(2); - fill(255, 200); - ellipse(location.x, location.y, mass*16, mass*16); - } - - // Bounce off bottom of window - void checkEdges() { - if (location.y > height) { - velocity.y *= -0.9; // A little dampening when hitting the bottom - location.y = height; - } - } -} - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/web-export/processing.js b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/web-export/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_5_fluidresistance_sequence/web-export/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/Attractor.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/Attractor.pde deleted file mode 100644 index 62115f590..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/Attractor.pde +++ /dev/null @@ -1,77 +0,0 @@ -// Attraction -// Daniel Shiffman - -// A class for a draggable attractive body in our world - -class Attractor { - float mass; // Mass, tied to size - float G; // Gravitational Constant - PVector location; // Location - boolean dragging = false; // Is the object being dragged? - boolean rollover = false; // Is the mouse over the ellipse? - PVector dragOffset; // holds the offset for when object is clicked on - - Attractor() { - location = new PVector(width/2,height/2); - mass = 20; - G = 1; - dragOffset = new PVector(0.0,0.0); - } - - PVector attract(Mover m) { - PVector force = PVector.sub(location,m.location); // Calculate direction of force - float d = force.mag(); // Distance between objects - d = constrain(d,5.0,25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects - force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction) - float strength = (G * mass * m.mass) / (d * d); // Calculate gravitional force magnitude - force.mult(strength); // Get force vector --> magnitude * direction - return force; - } - - // Method to display - void display() { - ellipseMode(CENTER); - strokeWeight(4); - stroke(0); - if (dragging) fill (50); - else if (rollover) fill(100); - else fill(175,200); - ellipse(location.x,location.y,mass*2,mass*2); - } - - // The methods below are for mouse interaction - void clicked(int mx, int my) { - float d = dist(mx,my,location.x,location.y); - if (d < mass) { - dragging = true; - dragOffset.x = location.x-mx; - dragOffset.y = location.y-my; - } - } - - void hover(int mx, int my) { - float d = dist(mx,my,location.x,location.y); - if (d < mass) { - rollover = true; - } - else { - rollover = false; - } - } - - void stopDragging() { - dragging = false; - } - - - - void drag() { - if (dragging) { - location.x = mouseX + dragOffset.x; - location.y = mouseY + dragOffset.y; - } - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/Mover.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/Mover.pde deleted file mode 100644 index ec2069b99..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/Mover.pde +++ /dev/null @@ -1,51 +0,0 @@ -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float mass; - - Mover() { - location = new PVector(400,50); - velocity = new PVector(1,0); - acceleration = new PVector(0,0); - mass = 1; - } - - void applyForce(PVector force) { - PVector f = PVector.div(force,mass); - acceleration.add(f); - } - - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - } - - void display() { - stroke(0); - strokeWeight(2); - fill(127); - ellipse(location.x,location.y,16,16); - } - - void checkEdges() { - - if (location.x > width) { - location.x = 0; - } else if (location.x < 0) { - location.x = width; - } - - if (location.y > height) { - velocity.y *= -1; - location.y = height; - } - - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/_2_6_attraction.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/_2_6_attraction.pde deleted file mode 100644 index 320ddc5ba..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/_2_6_attraction.pde +++ /dev/null @@ -1,36 +0,0 @@ -Mover m; -Attractor a; - -void setup() { - size(800,200); - smooth(); - m = new Mover(); - a = new Attractor(); -} - -void draw() { - background(255); - - PVector force = a.attract(m); - m.applyForce(force); - m.update(); - - a.drag(); - a.hover(mouseX,mouseY); - - a.display(); - m.display(); -} - -void mousePressed() { - a.clicked(mouseX,mouseY); -} - -void mouseReleased() { - a.stopDragging(); -} - - - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/sketch.properties b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/sketch.properties deleted file mode 100644 index 6d28cd598..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/sketch.properties +++ /dev/null @@ -1 +0,0 @@ -mode=JavaScript diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/web-export/_2_6_attraction.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/web-export/_2_6_attraction.pde deleted file mode 100644 index 28c59fedb..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/web-export/_2_6_attraction.pde +++ /dev/null @@ -1,165 +0,0 @@ -Mover m; -Attractor a; - -void setup() { - size(800,200); - smooth(); - m = new Mover(); - a = new Attractor(); -} - -void draw() { - background(255); - - PVector force = a.attract(m); - m.applyForce(force); - m.update(); - - a.drag(); - a.hover(mouseX,mouseY); - - a.display(); - m.display(); -} - -void mousePressed() { - a.clicked(mouseX,mouseY); -} - -void mouseReleased() { - a.stopDragging(); -} - - - - - -// Attraction -// Daniel Shiffman - -// A class for a draggable attractive body in our world - -class Attractor { - float mass; // Mass, tied to size - float G; // Gravitational Constant - PVector location; // Location - boolean dragging = false; // Is the object being dragged? - boolean rollover = false; // Is the mouse over the ellipse? - PVector dragOffset; // holds the offset for when object is clicked on - - Attractor() { - location = new PVector(width/2,height/2); - mass = 20; - G = 1; - dragOffset = new PVector(0.0,0.0); - } - - PVector attract(Mover m) { - PVector force = PVector.sub(location,m.location); // Calculate direction of force - float d = force.mag(); // Distance between objects - d = constrain(d,5.0,25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects - force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction) - float strength = (G * mass * m.mass) / (d * d); // Calculate gravitional force magnitude - force.mult(strength); // Get force vector --> magnitude * direction - return force; - } - - // Method to display - void display() { - ellipseMode(CENTER); - strokeWeight(4); - stroke(0); - if (dragging) fill (50); - else if (rollover) fill(100); - else fill(175,200); - ellipse(location.x,location.y,mass*2,mass*2); - } - - // The methods below are for mouse interaction - void clicked(int mx, int my) { - float d = dist(mx,my,location.x,location.y); - if (d < mass) { - dragging = true; - dragOffset.x = location.x-mx; - dragOffset.y = location.y-my; - } - } - - void hover(int mx, int my) { - float d = dist(mx,my,location.x,location.y); - if (d < mass) { - rollover = true; - } - else { - rollover = false; - } - } - - void stopDragging() { - dragging = false; - } - - - - void drag() { - if (dragging) { - location.x = mouseX + dragOffset.x; - location.y = mouseY + dragOffset.y; - } - } - -} - - -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float mass; - - Mover() { - location = new PVector(400,50); - velocity = new PVector(1,0); - acceleration = new PVector(0,0); - mass = 1; - } - - void applyForce(PVector force) { - PVector f = PVector.div(force,mass); - acceleration.add(f); - } - - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - } - - void display() { - stroke(0); - strokeWeight(2); - fill(127); - ellipse(location.x,location.y,16,16); - } - - void checkEdges() { - - if (location.x > width) { - location.x = 0; - } else if (location.x < 0) { - location.x = width; - } - - if (location.y > height) { - velocity.y *= -1; - location.y = height; - } - - } - -} - - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/web-export/processing.js b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/web-export/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_6_attraction/web-export/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_7_attraction_many/Attractor.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_7_attraction_many/Attractor.pde deleted file mode 100644 index 62115f590..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_7_attraction_many/Attractor.pde +++ /dev/null @@ -1,77 +0,0 @@ -// Attraction -// Daniel Shiffman - -// A class for a draggable attractive body in our world - -class Attractor { - float mass; // Mass, tied to size - float G; // Gravitational Constant - PVector location; // Location - boolean dragging = false; // Is the object being dragged? - boolean rollover = false; // Is the mouse over the ellipse? - PVector dragOffset; // holds the offset for when object is clicked on - - Attractor() { - location = new PVector(width/2,height/2); - mass = 20; - G = 1; - dragOffset = new PVector(0.0,0.0); - } - - PVector attract(Mover m) { - PVector force = PVector.sub(location,m.location); // Calculate direction of force - float d = force.mag(); // Distance between objects - d = constrain(d,5.0,25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects - force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction) - float strength = (G * mass * m.mass) / (d * d); // Calculate gravitional force magnitude - force.mult(strength); // Get force vector --> magnitude * direction - return force; - } - - // Method to display - void display() { - ellipseMode(CENTER); - strokeWeight(4); - stroke(0); - if (dragging) fill (50); - else if (rollover) fill(100); - else fill(175,200); - ellipse(location.x,location.y,mass*2,mass*2); - } - - // The methods below are for mouse interaction - void clicked(int mx, int my) { - float d = dist(mx,my,location.x,location.y); - if (d < mass) { - dragging = true; - dragOffset.x = location.x-mx; - dragOffset.y = location.y-my; - } - } - - void hover(int mx, int my) { - float d = dist(mx,my,location.x,location.y); - if (d < mass) { - rollover = true; - } - else { - rollover = false; - } - } - - void stopDragging() { - dragging = false; - } - - - - void drag() { - if (dragging) { - location.x = mouseX + dragOffset.x; - location.y = mouseY + dragOffset.y; - } - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_7_attraction_many/Mover.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_7_attraction_many/Mover.pde deleted file mode 100644 index 91712f09d..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_7_attraction_many/Mover.pde +++ /dev/null @@ -1,33 +0,0 @@ -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float mass; - - Mover(float m, float x, float y) { - mass = m; - location = new PVector(random(width), random(height)); - velocity = new PVector(1, 0); - acceleration = new PVector(0, 0); - } - - void applyForce(PVector force) { - PVector f = PVector.div(force, mass); - acceleration.add(f); - } - - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - } - - void display() { - stroke(0); - strokeWeight(2); - fill(0,100); - ellipse(location.x, location.y, mass*25, mass*25); - } -} - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_7_attraction_many/_2_7_attraction_many.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_7_attraction_many/_2_7_attraction_many.pde deleted file mode 100644 index a213c79be..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_7_attraction_many/_2_7_attraction_many.pde +++ /dev/null @@ -1,46 +0,0 @@ -Mover[] movers = new Mover[10]; - -Attractor a; - -void setup() { - size(800, 200); - smooth(); - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(random(0.1, 2), random(width), random(height)); - } - a = new Attractor(); - } - -void draw() { - background(255); - - a.display(); - a.drag(); - a.hover(mouseX, mouseY); - - for (int i = 0; i < movers.length; i++) { - PVector force = a.attract(movers[i]); - movers[i].applyForce(force); - - movers[i].update(); - movers[i].display(); - } -} - -void mousePressed() { - a.clicked(mouseX, mouseY); -} - -void mouseReleased() { - a.stopDragging(); -} - - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/Mover.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/Mover.pde deleted file mode 100644 index 30c49d701..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/Mover.pde +++ /dev/null @@ -1,48 +0,0 @@ -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float mass; - - Mover(float m, float x, float y) { - mass = m; - location = new PVector(x, y); - velocity = new PVector(0, 0); - acceleration = new PVector(0, 0); - } - - void applyForce(PVector force) { - PVector f = PVector.div(force, mass); - acceleration.add(f); - } - - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - } - - void display() { - stroke(0); - strokeWeight(2); - fill(0, 100); - ellipse(location.x, location.y, mass*24, mass*24); - } - - PVector attract(Mover m) { - PVector force = PVector.sub(location, m.location); // Calculate direction of force - float distance = force.mag(); // Distance between objects - distance = constrain(distance, 5.0, 25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects - force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction - - float strength = (g * mass * m.mass) / (distance * distance); // Calculate gravitional force magnitude - force.mult(strength); // Get force vector --> magnitude * direction - return force; - } - - -} - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/_2_8_mutual_attraction.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/_2_8_mutual_attraction.pde deleted file mode 100644 index 905140372..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/_2_8_mutual_attraction.pde +++ /dev/null @@ -1,42 +0,0 @@ -Mover[] movers = new Mover[20]; - -float g = 0.4; - -void setup() { - size(800,200); - smooth(); - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(random(0.1,2),random(width),random(height)); - } -} - -void draw() { - background(255); - - - for (int i = 0; i < movers.length; i++) { - for (int j = 0; j < movers.length; j++) { - if (i != j) { - PVector force = movers[j].attract(movers[i]); - movers[i].applyForce(force); - } - } - - movers[i].update(); - movers[i].display(); - } - -} - - - - - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/sketch.properties b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/sketch.properties deleted file mode 100644 index 6d28cd598..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/sketch.properties +++ /dev/null @@ -1 +0,0 @@ -mode=JavaScript diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/web-export/_2_8_mutual_attraction.pde b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/web-export/_2_8_mutual_attraction.pde deleted file mode 100644 index 3ca1f568c..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/web-export/_2_8_mutual_attraction.pde +++ /dev/null @@ -1,91 +0,0 @@ -Mover[] movers = new Mover[20]; - -float g = 0.4; - -void setup() { - size(800,200); - smooth(); - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(random(0.1,2),random(width),random(height)); - } -} - -void draw() { - background(255); - - - for (int i = 0; i < movers.length; i++) { - for (int j = 0; j < movers.length; j++) { - if (i != j) { - PVector force = movers[j].attract(movers[i]); - movers[i].applyForce(force); - } - } - - movers[i].update(); - movers[i].display(); - } - -} - - - - - - - - - - - - - -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float mass; - - Mover(float m, float x, float y) { - mass = m; - location = new PVector(x, y); - velocity = new PVector(0, 0); - acceleration = new PVector(0, 0); - } - - void applyForce(PVector force) { - PVector f = PVector.div(force, mass); - acceleration.add(f); - } - - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - } - - void display() { - stroke(0); - strokeWeight(2); - fill(0, 100); - ellipse(location.x, location.y, mass*24, mass*24); - } - - PVector attract(Mover m) { - PVector force = PVector.sub(location, m.location); // Calculate direction of force - float distance = force.mag(); // Distance between objects - distance = constrain(distance, 5.0, 25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects - force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction - - float strength = (g * mass * m.mass) / (distance * distance); // Calculate gravitional force magnitude - force.mult(strength); // Get force vector --> magnitude * direction - return force; - } - - -} - - - - diff --git a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/web-export/processing.js b/java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/web-export/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp2_forces/NOC_2_8_mutual_attraction/web-export/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/AdditiveWave/AdditiveWave.pde b/java/examples/Books/Nature of Code/chp3_oscillation/AdditiveWave/AdditiveWave.pde deleted file mode 100644 index 888f4b142..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/AdditiveWave/AdditiveWave.pde +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Additive Wave - * by Daniel Shiffman. - * - * Create a more complex wave by adding two waves together. - */ - -// Maybe better for this answer to be OOP??? - -int xspacing = 8; // How far apart should each horizontal location be spaced -int w; // Width of entire wave -int maxwaves = 5; // total # of waves to add together - -float theta = 0.0; -float[] amplitude = new float[maxwaves]; // Height of wave -float[] dx = new float[maxwaves]; // Value for incrementing X, to be calculated as a function of period and xspacing -float[] yvalues; // Using an array to store height values for the wave (not entirely necessary) - -void setup() { - size(640,360); - colorMode(RGB, 255, 255, 255, 100); - smooth(); - w = width + 16; - - for (int i = 0; i < maxwaves; i++) { - amplitude[i] = random(10,30); - float period = random(100,300); // How many pixels before the wave repeats - dx[i] = (TWO_PI / period) * xspacing; - } - - yvalues = new float[w/xspacing]; -} - -void draw() { - background(0); - calcWave(); - renderWave(); -} - -void calcWave() { - // Increment theta (try different values for 'angular velocity' here - theta += 0.02; - - // Set all height values to zero - for (int i = 0; i < yvalues.length; i++) { - yvalues[i] = 0; - } - - // Accumulate wave height values - for (int j = 0; j < maxwaves; j++) { - float x = theta; - for (int i = 0; i < yvalues.length; i++) { - // Every other wave is cosine instead of sine - if (j % 2 == 0) yvalues[i] += sin(x)*amplitude[j]; - else yvalues[i] += cos(x)*amplitude[j]; - x+=dx[j]; - } - } -} - -void renderWave() { - // A simple way to draw the wave with an ellipse at each location - noStroke(); - fill(255,50); - ellipseMode(CENTER); - for (int x = 0; x < yvalues.length; x++) { - ellipse(x*xspacing,height/2+yvalues[x],16,16); - } -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/AttractionArrayWithOscillation/AttractionArrayWithOscillation.pde b/java/examples/Books/Nature of Code/chp3_oscillation/AttractionArrayWithOscillation/AttractionArrayWithOscillation.pde deleted file mode 100644 index abfa74f4e..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/AttractionArrayWithOscillation/AttractionArrayWithOscillation.pde +++ /dev/null @@ -1,46 +0,0 @@ -// Attraction Array with Oscillating objects around each Crawler -// Daniel Shiffman -// Nature of Code, Spring 2012 - -// Click and drag attractive body to move throughout space - -Crawler[] crawlers = new Crawler[6]; -Attractor a; - -void setup() { - size(640,360); - smooth(); - - // Some random bodies - for (int i = 0; i < crawlers.length; i++) { - crawlers[i] = new Crawler(); - } - // Create an attractive body - a = new Attractor(new PVector(width/2,height/2),20,0.4); -} - -void draw() { - background(255); - a.rollover(mouseX,mouseY); - a.go(); - - for (int i = 0; i < crawlers.length; i++) { - // Calculate a force exerted by "attractor" on "Crawler" - PVector f = a.attract(crawlers[i]); - // Apply that force to the Crawler - crawlers[i].applyForce(f); - // Update and render - crawlers[i].update(); - crawlers[i].display(); - } - - -} - -void mousePressed() { - a.clicked(mouseX,mouseY); -} - -void mouseReleased() { - a.stopDragging(); -} diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/AttractionArrayWithOscillation/Attractor.pde b/java/examples/Books/Nature of Code/chp3_oscillation/AttractionArrayWithOscillation/Attractor.pde deleted file mode 100644 index b725c771a..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/AttractionArrayWithOscillation/Attractor.pde +++ /dev/null @@ -1,81 +0,0 @@ -// Attraction -// Daniel Shiffman -// Nature of Code, Spring 2009 - - -// A class for a draggable attractive body in our world - -class Attractor { - float mass; // Mass, tied to size - float G; // Gravitational Constant - PVector loc; // Location - boolean dragging = false; // Is the object being dragged? - boolean rollover = false; // Is the mouse over the ellipse? - PVector drag; // holds the offset for when object is clicked on - - Attractor(PVector l_,float m_, float g_) { - loc = l_.get(); - mass = m_; - G = g_; - drag = new PVector(0.0,0.0); - } - - void go() { - render(); - drag(); - } - - PVector attract(Crawler c) { - PVector dir = PVector.sub(loc,c.loc); // Calculate direction of force - float d = dir.mag(); // Distance between objects - d = constrain(d,5.0,25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects - dir.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction) - float force = (G * mass * c.mass) / (d * d); // Calculate gravitional force magnitude - dir.mult(force); // Get force vector --> magnitude * direction - return dir; - } - - // Method to display - void render() { - ellipseMode(CENTER); - stroke(0,100); - if (dragging) fill (50); - else if (rollover) fill(100); - else fill(175,50); - ellipse(loc.x,loc.y,mass*2,mass*2); - } - - // The methods below are for mouse interaction - void clicked(int mx, int my) { - float d = dist(mx,my,loc.x,loc.y); - if (d < mass) { - dragging = true; - drag.x = loc.x-mx; - drag.y = loc.y-my; - } - } - - void rollover(int mx, int my) { - float d = dist(mx,my,loc.x,loc.y); - if (d < mass) { - rollover = true; - } else { - rollover = false; - } - } - - void stopDragging() { - dragging = false; - } - - - - void drag() { - if (dragging) { - loc.x = mouseX + drag.x; - loc.y = mouseY + drag.y; - } - } - -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/AttractionArrayWithOscillation/Crawler.pde b/java/examples/Books/Nature of Code/chp3_oscillation/AttractionArrayWithOscillation/Crawler.pde deleted file mode 100644 index 35ae63222..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/AttractionArrayWithOscillation/Crawler.pde +++ /dev/null @@ -1,56 +0,0 @@ -// Attraction -// Daniel Shiffman -// Nature of Code, Spring 2012 - -// A class to describe a thing in our world, has vectors for location, velocity, and acceleration -// Also includes scalar values for mass, maximum velocity, and elasticity - -class Crawler { - PVector loc; - PVector vel; - PVector acc; - float mass; - - Oscillator osc; - - Crawler() { - acc = new PVector(); - vel = new PVector(random(-1,1),random(-1,1)); - loc = new PVector(random(width),random(height)); - mass = random(8,16); - osc = new Oscillator(mass*2); - } - - void applyForce(PVector force) { - PVector f = force.get(); - f.div(mass); - acc.add(f); - } - - // Method to update location - void update() { - vel.add(acc); - loc.add(vel); - // Multiplying by 0 sets the all the components to 0 - acc.mult(0); - - osc.update(vel.mag()/10); - } - - // Method to display - void display() { - float angle = vel.heading2D(); - pushMatrix(); - translate(loc.x,loc.y); - rotate(angle); - ellipseMode(CENTER); - stroke(0); - fill(175,100); - ellipse(0,0,mass*2,mass*2); - - osc.display(loc); - popMatrix(); - - } -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/AttractionArrayWithOscillation/Oscillator.pde b/java/examples/Books/Nature of Code/chp3_oscillation/AttractionArrayWithOscillation/Oscillator.pde deleted file mode 100644 index 624156fbf..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/AttractionArrayWithOscillation/Oscillator.pde +++ /dev/null @@ -1,35 +0,0 @@ -// Attraction Array with Oscillating objects around each thing -// Daniel Shiffman -// Nature of Code, Spring 2009 - -class Oscillator { - - // Because we are going to oscillate along the x and y axis we can use PVector for two angles, amplitudes, etc.! - float theta; - float amplitude; - - Oscillator(float r) { - - // Initialize randomly - theta = 0; - amplitude = r; - - } - - // Update theta and offset - void update(float thetaVel) { - theta += thetaVel; - } - - // Display based on a location - void display(PVector loc) { - float x = map(cos(theta),-1,1,0,amplitude); - - stroke(0); - fill(50); - line(0,0,x,0); - ellipse(x,0,8,8); - } -} - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_01_exercise_baton/Ex_3_01_exercise_baton.pde b/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_01_exercise_baton/Ex_3_01_exercise_baton.pde deleted file mode 100644 index 3eadcc85e..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_01_exercise_baton/Ex_3_01_exercise_baton.pde +++ /dev/null @@ -1,24 +0,0 @@ -float angle = 0; - -void setup() { - size(750, 150); - smooth(); -} - -void draw() { - background(255); - - fill(127); - stroke(0); - rectMode(CENTER); - translate(width/2, height/2); - rotate(angle); - line(-50, 0, 50, 0); - stroke(0); - strokeWeight(2); - fill(127); - ellipse(50, 0, 16, 16); - ellipse(-50, 0, 16, 16); - angle += 0.05; -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_04_spiral/Ex_3_04_spiral.pde b/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_04_spiral/Ex_3_04_spiral.pde deleted file mode 100644 index 94611d5b0..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_04_spiral/Ex_3_04_spiral.pde +++ /dev/null @@ -1,30 +0,0 @@ -// Nature of Code -// Daniel Shiffman -// http://www.learningprocessing.com - -// A Polar coordinate, radius now starts at 0 to spiral outwards -float r = 0; -float theta = 0; - -void setup() { - size(750,200); - background(255); - smooth(); -} - -void draw() { - // Polar to Cartesian conversion - float x = r * cos(theta); - float y = r * sin(theta); - - // Draw an ellipse at x,y - noStroke(); - fill(0); - // Adjust for center of window - ellipse(x+width/2, y+height/2, 16, 16); - - // Increment the angle - theta += 0.01; - // Increment the radius - r += 0.05; -} diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_05_asteroids/Ex_3_05_asteroids.pde b/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_05_asteroids/Ex_3_05_asteroids.pde deleted file mode 100644 index 239de3fd2..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_05_asteroids/Ex_3_05_asteroids.pde +++ /dev/null @@ -1,41 +0,0 @@ -// Nature of Code 2011 -// Daniel Shiffman -// Chapter 3: Asteroids exercise -// http://www.shiffman.net - -// Mover object -Spaceship ship; - -void setup() { - size(750, 200); - smooth(); - ship = new Spaceship(); -} - -void draw() { - background(255); - - // Update location - ship.update(); - // Wrape edges - ship.wrapEdges(); - // Draw ship - ship.display(); - - - fill(0); - text("left right arrows to turn, z to thrust",10,height-5); - - // Turn or thrust the ship depending on what key is pressed - if (keyPressed) { - if (key == CODED && keyCode == LEFT) { - ship.turn(-0.03); - } else if (key == CODED && keyCode == RIGHT) { - ship.turn(0.03); - } else if (key == 'z' || key == 'Z') { - ship.thrust(); - } - } -} - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_05_asteroids/Spaceship.pde b/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_05_asteroids/Spaceship.pde deleted file mode 100644 index 1910c7243..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_05_asteroids/Spaceship.pde +++ /dev/null @@ -1,97 +0,0 @@ -// Nature of Code 2011 -// Daniel Shiffman -// Chapter 3: Asteroids - -class Spaceship { - // All of our regular motion stuff - PVector location; - PVector velocity; - PVector acceleration; - - // Arbitrary damping to slow down ship - float damping = 0.995; - float topspeed = 6; - - // Variable for heading! - float heading = 0; - - // Size - float r = 16; - - // Are we thrusting (to color boosters) - boolean thrusting = false; - - Spaceship() { - location = new PVector(width/2,height/2); - velocity = new PVector(); - acceleration = new PVector(); - } - - // Standard Euler integration - void update() { - velocity.add(acceleration); - velocity.mult(damping); - velocity.limit(topspeed); - location.add(velocity); - acceleration.mult(0); - } - - // Newton's law: F = M * A - void applyForce(PVector force) { - PVector f = force.get(); - //f.div(mass); // ignoring mass right now - acceleration.add(f); - } - - // Turn changes angle - void turn(float a) { - heading += a; - } - - // Apply a thrust force - void thrust() { - // Offset the angle since we drew the ship vertically - float angle = heading - PI/2; - // Polar to cartesian for force vector! - PVector force = new PVector(cos(angle),sin(angle)); - force.mult(0.1); - applyForce(force); - // To draw booster - thrusting = true; - } - - void wrapEdges() { - float buffer = r*2; - if (location.x > width + buffer) location.x = -buffer; - else if (location.x < -buffer) location.x = width+buffer; - if (location.y > height + buffer) location.y = -buffer; - else if (location.y < -buffer) location.y = height+buffer; - } - - - // Draw the ship - void display() { - stroke(0); - strokeWeight(2); - pushMatrix(); - translate(location.x,location.y+r); - rotate(heading); - fill(175); - if (thrusting) fill(255,0,0); - // Booster rockets - rect(-r/2,r,r/3,r/2); - rect(r/2,r,r/3,r/2); - fill(175); - // A triangle - beginShape(); - vertex(-r,r); - vertex(0,-r); - vertex(r,r); - endShape(CLOSE); - rectMode(CENTER); - popMatrix(); - - thrusting = false; - } -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_10_OOPWave/Ex_3_10_OOPWave.pde b/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_10_OOPWave/Ex_3_10_OOPWave.pde deleted file mode 100644 index be26ff0f4..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_10_OOPWave/Ex_3_10_OOPWave.pde +++ /dev/null @@ -1,31 +0,0 @@ -// Sine Wave -// Daniel Shiffman - - -// Two wave objects -Wave wave0; -Wave wave1; - -void setup() { - size(750,200); - smooth(); - // Initialize a wave with starting point, width, amplitude, and period - wave0 = new Wave(new PVector(50,75),100,20,500); - wave1 = new Wave(new PVector(300,100),300,40,220); - -} - -void draw() { - background(255); - - // Update and display waves - wave0.calculate(); - wave0.display(); - - wave1.calculate(); - wave1.display(); - - -} - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_10_OOPWave/Wave.pde b/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_10_OOPWave/Wave.pde deleted file mode 100644 index 1ecf976c0..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_10_OOPWave/Wave.pde +++ /dev/null @@ -1,45 +0,0 @@ -class Wave { - - int xspacing = 8; // How far apart should each horizontal location be spaced - int w; // Width of entire wave - - PVector origin; // Where does the wave's first point start - float theta = 0.0; // Start angle at 0 - float amplitude; // Height of wave - float period; // How many pixels before the wave repeats - float dx; // Value for incrementing X, to be calculated as a function of period and xspacing - float[] yvalues; // Using an array to store height values for the wave (not entirely necessary) - - Wave(PVector o, int w_, float a, float p) { - origin = o.get(); - w = w_; - period = p; - amplitude = a; - dx = (TWO_PI / period) * xspacing; - yvalues = new float[w/xspacing]; - } - - - void calculate() { - // Increment theta (try different values for 'angular velocity' here - theta += 0.02; - - // For every x value, calculate a y value with sine function - float x = theta; - for (int i = 0; i < yvalues.length; i++) { - yvalues[i] = sin(x)*amplitude; - x+=dx; - } - } - - void display() { - // A simple way to draw the wave with an ellipse at each location - for (int x = 0; x < yvalues.length; x++) { - stroke(0); - fill(0,50); - ellipseMode(CENTER); - ellipse(origin.x+x*xspacing,origin.y+yvalues[x],48,48); - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_11_AdditiveWave/Ex_3_11_AdditiveWave.pde b/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_11_AdditiveWave/Ex_3_11_AdditiveWave.pde deleted file mode 100644 index 316721bef..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/Exercise_3_11_AdditiveWave/Ex_3_11_AdditiveWave.pde +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Additive Wave - * by Daniel Shiffman. - * - * Create a more complex wave by adding two waves together. - */ - -// Maybe better for this answer to be OOP??? - -int xspacing = 8; // How far apart should each horizontal location be spaced -int w; // Width of entire wave -int maxwaves = 5; // total # of waves to add together - -float theta = 0.0; -float[] amplitude = new float[maxwaves]; // Height of wave -float[] dx = new float[maxwaves]; // Value for incrementing X, to be calculated as a function of period and xspacing -float[] yvalues; // Using an array to store height values for the wave (not entirely necessary) - -void setup() { - size(750,200); - smooth(); - w = width + 16; - - for (int i = 0; i < maxwaves; i++) { - amplitude[i] = random(10,30); - float period = random(100,300); // How many pixels before the wave repeats - dx[i] = (TWO_PI / period) * xspacing; - } - - yvalues = new float[w/xspacing]; -} - -void draw() { - background(255); - calcWave(); - renderWave(); -} - -void calcWave() { - // Increment theta (try different values for 'angular velocity' here - theta += 0.02; - - // Set all height values to zero - for (int i = 0; i < yvalues.length; i++) { - yvalues[i] = 0; - } - - // Accumulate wave height values - for (int j = 0; j < maxwaves; j++) { - float x = theta; - for (int i = 0; i < yvalues.length; i++) { - // Every other wave is cosine instead of sine - if (j % 2 == 0) yvalues[i] += sin(x)*amplitude[j]; - else yvalues[i] += cos(x)*amplitude[j]; - x+=dx[j]; - } - } -} - -void renderWave() { - // A simple way to draw the wave with an ellipse at each location - stroke(0); - fill(127,50); - ellipseMode(CENTER); - for (int x = 0; x < yvalues.length; x++) { - ellipse(x*xspacing,height/2+yvalues[x],48,48); - } -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_03spring_exercise_sine/_03spring_exercise_sine.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_03spring_exercise_sine/_03spring_exercise_sine.pde deleted file mode 100644 index 26ba2c139..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_03spring_exercise_sine/_03spring_exercise_sine.pde +++ /dev/null @@ -1,21 +0,0 @@ -float angle = 0; -float aVelocity = 0.05; - -void setup() { - size(640,360); - smooth(); -} - -void draw() { - background(255); - - float x = width/2; - float y = map(sin(angle),-1,1,50,250); - angle += aVelocity; - - ellipseMode(CENTER); - stroke(0); - fill(175); - line(x,0,x,y); - ellipse(x,y,20,20); -} diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_01_angular_motion/_3_01_angular_motion.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_01_angular_motion/_3_01_angular_motion.pde deleted file mode 100644 index f88335f6b..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_01_angular_motion/_3_01_angular_motion.pde +++ /dev/null @@ -1,30 +0,0 @@ -float angle = 0; -float aVelocity = 0; -float aAcceleration = 0.0001; - -void setup() { - size(800, 200); - smooth(); -} - -void draw() { - background(255); - - - fill(127); - stroke(0); - - translate(width/2, height/2); - rectMode(CENTER); - rotate(angle); - stroke(0); - strokeWeight(2); - fill(127); - line(-60, 0, 60, 0); - ellipse(60, 0, 16, 16); - ellipse(-60, 0, 16, 16); - - angle += aVelocity; - aVelocity += aAcceleration; -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_01_angular_motion_trail/_3_01_angular_motion_trail.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_01_angular_motion_trail/_3_01_angular_motion_trail.pde deleted file mode 100644 index c33166cf9..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_01_angular_motion_trail/_3_01_angular_motion_trail.pde +++ /dev/null @@ -1,35 +0,0 @@ -float angle = 0; -float aVelocity = 0; -float aAcceleration = 0.0001; - -void setup() { - size(800, 200); - background(255); - smooth(); -} - -void draw() { - //background(255); - rectMode(CORNER); - noStroke(); - fill(255,5); - rect(0,0,width,height); - - - fill(127); - stroke(0); - - translate(width/2, height/2); - rectMode(CENTER); - rotate(angle); - stroke(0); - strokeWeight(2); - fill(127); - line(-60, 0, 60, 0); - ellipse(60, 0, 16, 16); - ellipse(-60, 0, 16, 16); - - angle += aVelocity; - aVelocity += aAcceleration; -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_mot_trails/Attractor.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_mot_trails/Attractor.pde deleted file mode 100644 index 56628fdf1..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_mot_trails/Attractor.pde +++ /dev/null @@ -1,36 +0,0 @@ -// Attraction -// Daniel Shiffman - -// A class for a draggable attractive body in our world - -class Attractor { - float mass; // Mass, tied to size - PVector location; // Location - float g; - - Attractor() { - location = new PVector(width/2, height/2); - mass = 20; - g = 0.4; - } - - - PVector attract(Mover m) { - PVector force = PVector.sub(location, m.location); // Calculate direction of force - float distance = force.mag(); // Distance between objects - distance = constrain(distance, 5.0, 25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects - force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction) - float strength = (g * mass * m.mass) / (distance * distance); // Calculate gravitional force magnitude - force.mult(strength); // Get force vector --> magnitude * direction - return force; - } - - // Method to display - void display() { - stroke(0); - strokeWeight(2); - fill(127); - ellipse(location.x, location.y, 48, 48); - } -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_mot_trails/Mover.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_mot_trails/Mover.pde deleted file mode 100644 index 1ff6e5750..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_mot_trails/Mover.pde +++ /dev/null @@ -1,49 +0,0 @@ -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float mass; - - float angle = 0; - float aVelocity = 0; - float aAcceleration = 0; - - Mover(float m, float x, float y) { - mass = m; - location = new PVector(x,y); - velocity = new PVector(random(-1,1),random(-1,1)); - acceleration = new PVector(0,0); - } - - void applyForce(PVector force) { - PVector f = PVector.div(force,mass); - acceleration.add(f); - } - - void update() { - - velocity.add(acceleration); - location.add(velocity); - - aAcceleration = acceleration.x / 10.0; - aVelocity += aAcceleration; - aVelocity = constrain(aVelocity,-0.1,0.1); - angle += aVelocity; - - acceleration.mult(0); - } - - void display() { - stroke(0); - fill(175,200); - rectMode(CENTER); - pushMatrix(); - translate(location.x,location.y); - rotate(angle); - rect(0,0,mass*16,mass*16); - popMatrix(); - } - -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_mot_trails/_3_02_forces_angular_mot_trails.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_mot_trails/_3_02_forces_angular_mot_trails.pde deleted file mode 100644 index ec850608d..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_mot_trails/_3_02_forces_angular_mot_trails.pde +++ /dev/null @@ -1,44 +0,0 @@ -Mover[] movers = new Mover[20]; - -Attractor a; - -void setup() { - size(800,200); - smooth(); - background(255); - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(random(0.1,2),random(width),random(height)); - } - a = new Attractor(); -} - -void draw() { - //background(255); - - rectMode(CORNER); - noStroke(); - fill(255,5); - rect(0,0,width,height); - - a.display(); - - for (int i = 0; i < movers.length; i++) { - PVector force = a.attract(movers[i]); - movers[i].applyForce(force); - - movers[i].update(); - movers[i].display(); - } - -} - - - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_motion/Attractor.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_motion/Attractor.pde deleted file mode 100644 index 56628fdf1..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_motion/Attractor.pde +++ /dev/null @@ -1,36 +0,0 @@ -// Attraction -// Daniel Shiffman - -// A class for a draggable attractive body in our world - -class Attractor { - float mass; // Mass, tied to size - PVector location; // Location - float g; - - Attractor() { - location = new PVector(width/2, height/2); - mass = 20; - g = 0.4; - } - - - PVector attract(Mover m) { - PVector force = PVector.sub(location, m.location); // Calculate direction of force - float distance = force.mag(); // Distance between objects - distance = constrain(distance, 5.0, 25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects - force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction) - float strength = (g * mass * m.mass) / (distance * distance); // Calculate gravitional force magnitude - force.mult(strength); // Get force vector --> magnitude * direction - return force; - } - - // Method to display - void display() { - stroke(0); - strokeWeight(2); - fill(127); - ellipse(location.x, location.y, 48, 48); - } -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_motion/Mover.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_motion/Mover.pde deleted file mode 100644 index 1ff6e5750..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_motion/Mover.pde +++ /dev/null @@ -1,49 +0,0 @@ -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float mass; - - float angle = 0; - float aVelocity = 0; - float aAcceleration = 0; - - Mover(float m, float x, float y) { - mass = m; - location = new PVector(x,y); - velocity = new PVector(random(-1,1),random(-1,1)); - acceleration = new PVector(0,0); - } - - void applyForce(PVector force) { - PVector f = PVector.div(force,mass); - acceleration.add(f); - } - - void update() { - - velocity.add(acceleration); - location.add(velocity); - - aAcceleration = acceleration.x / 10.0; - aVelocity += aAcceleration; - aVelocity = constrain(aVelocity,-0.1,0.1); - angle += aVelocity; - - acceleration.mult(0); - } - - void display() { - stroke(0); - fill(175,200); - rectMode(CENTER); - pushMatrix(); - translate(location.x,location.y); - rotate(angle); - rect(0,0,mass*16,mass*16); - popMatrix(); - } - -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_motion/_3_02_forces_angular_motion.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_motion/_3_02_forces_angular_motion.pde deleted file mode 100644 index c5c454ea5..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_02_forces_angular_motion/_3_02_forces_angular_motion.pde +++ /dev/null @@ -1,39 +0,0 @@ -Mover[] movers = new Mover[20]; - -Attractor a; - -void setup() { - size(800,200); - smooth(); - background(255); - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(random(0.1,2),random(width),random(height)); - } - a = new Attractor(); -} - -void draw() { - background(255); - - a.display(); - - for (int i = 0; i < movers.length; i++) { - PVector force = a.attract(movers[i]); - movers[i].applyForce(force); - - movers[i].update(); - movers[i].display(); - } - -} - - - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_03_pointing_velocity/Mover.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_03_pointing_velocity/Mover.pde deleted file mode 100644 index b3f9f770b..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_03_pointing_velocity/Mover.pde +++ /dev/null @@ -1,65 +0,0 @@ -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float topspeed; - - float xoff, yoff; - - float r = 16; - - Mover() { - location = new PVector(width/2, height/2); - velocity = new PVector(0, 0); - topspeed = 4; - xoff = 1000; - yoff = 0; - } - - void update() { - - PVector mouse = new PVector(mouseX, mouseY); - PVector dir = PVector.sub(mouse, location); - dir.normalize(); - dir.mult(0.5); - acceleration = dir; - - velocity.add(acceleration); - velocity.limit(topspeed); - location.add(velocity); - } - - void display() { - float theta = velocity.heading2D(); - - stroke(0); - strokeWeight(2); - fill(127); - pushMatrix(); - rectMode(CENTER); - translate(location.x, location.y); - rotate(theta); - rect(0, 0, 30, 10); - popMatrix(); - } - - void checkEdges() { - - if (location.x > width) { - location.x = 0; - } - else if (location.x < 0) { - location.x = width; - } - - if (location.y > height) { - location.y = 0; - } - else if (location.y < 0) { - location.y = height; - } - } -} - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_03_pointing_velocity/_3_03_pointing_velocity.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_03_pointing_velocity/_3_03_pointing_velocity.pde deleted file mode 100644 index eb3d55ee4..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_03_pointing_velocity/_3_03_pointing_velocity.pde +++ /dev/null @@ -1,17 +0,0 @@ -Mover mover; - -void setup() { - size(800,200); - smooth(); - mover = new Mover(); -} - -void draw() { - background(255); - - mover.update(); - mover.checkEdges(); - mover.display(); -} - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_03_pointing_velocity_trail/Mover.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_03_pointing_velocity_trail/Mover.pde deleted file mode 100644 index b3f9f770b..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_03_pointing_velocity_trail/Mover.pde +++ /dev/null @@ -1,65 +0,0 @@ -class Mover { - - PVector location; - PVector velocity; - PVector acceleration; - float topspeed; - - float xoff, yoff; - - float r = 16; - - Mover() { - location = new PVector(width/2, height/2); - velocity = new PVector(0, 0); - topspeed = 4; - xoff = 1000; - yoff = 0; - } - - void update() { - - PVector mouse = new PVector(mouseX, mouseY); - PVector dir = PVector.sub(mouse, location); - dir.normalize(); - dir.mult(0.5); - acceleration = dir; - - velocity.add(acceleration); - velocity.limit(topspeed); - location.add(velocity); - } - - void display() { - float theta = velocity.heading2D(); - - stroke(0); - strokeWeight(2); - fill(127); - pushMatrix(); - rectMode(CENTER); - translate(location.x, location.y); - rotate(theta); - rect(0, 0, 30, 10); - popMatrix(); - } - - void checkEdges() { - - if (location.x > width) { - location.x = 0; - } - else if (location.x < 0) { - location.x = width; - } - - if (location.y > height) { - location.y = 0; - } - else if (location.y < 0) { - location.y = height; - } - } -} - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_03_pointing_velocity_trail/_3_03_pointing_velocity_trail.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_03_pointing_velocity_trail/_3_03_pointing_velocity_trail.pde deleted file mode 100644 index d0d7f776e..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_03_pointing_velocity_trail/_3_03_pointing_velocity_trail.pde +++ /dev/null @@ -1,25 +0,0 @@ -Mover mover; - -void setup() { - size(800,200); - background(255); - smooth(); - mover = new Mover(); -} - -void draw() { - if (mousePressed) { - //background(255); - rectMode(CORNER); - noStroke(); - fill(255,5); - rect(0,0,width,height); - - mover.update(); - mover.checkEdges(); - mover.display(); - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_04_PolarToCartesian/_3_04_PolarToCartesian.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_04_PolarToCartesian/_3_04_PolarToCartesian.pde deleted file mode 100644 index 070f60e14..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_04_PolarToCartesian/_3_04_PolarToCartesian.pde +++ /dev/null @@ -1,50 +0,0 @@ -/** - * PolarToCartesian - * by Daniel Shiffman. - * - * Convert a polar coordinate (r,theta) to cartesian (x,y): - * x = r * cos(theta) - * y = r * sin(theta) - */ - -float r; -float theta; - - -void setup() { - size(800, 200); - smooth(); - - // Initialize all values - r = height * 0.45; - theta = 0; -} - -void draw() { - - background(255); - - // Translate the origin point to the center of the screen - translate(width/2, height/2); - - // Convert polar to cartesian - float x = r * cos(theta); - float y = r * sin(theta); - - // Draw the ellipse at the cartesian coordinate - ellipseMode(CENTER); - fill(127); - stroke(0); - strokeWeight(2); - line(0,0,x,y); - ellipse(x, y, 48, 48); - - // Increase the angle over time - theta += 0.02; - - -} - - - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_04_PolarToCartesian_trail/_3_04_PolarToCartesian_trail.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_04_PolarToCartesian_trail/_3_04_PolarToCartesian_trail.pde deleted file mode 100644 index 6e8a2ca40..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_04_PolarToCartesian_trail/_3_04_PolarToCartesian_trail.pde +++ /dev/null @@ -1,54 +0,0 @@ -/** - * PolarToCartesian - * by Daniel Shiffman. - * - * Convert a polar coordinate (r,theta) to cartesian (x,y): - * x = r * cos(theta) - * y = r * sin(theta) - */ - -float r; -float theta; - - -void setup() { - size(800, 200); - background(255); - smooth(); - - // Initialize all values - r = height * 0.45; - theta = 0; -} - -void draw() { - - //background(255); - noStroke(); - fill(255,5); - rect(0,0,width,height); - - // Translate the origin point to the center of the screen - translate(width/2, height/2); - - // Convert polar to cartesian - float x = r * cos(theta); - float y = r * sin(theta); - - // Draw the ellipse at the cartesian coordinate - ellipseMode(CENTER); - fill(127); - stroke(0); - strokeWeight(2); - line(0,0,x,y); - ellipse(x, y, 48, 48); - - // Increase the angle over time - theta += 0.02; - - -} - - - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_05_simple_harmonic_mot_trail/_3_05_simple_harmonic_mot_trail.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_05_simple_harmonic_mot_trail/_3_05_simple_harmonic_mot_trail.pde deleted file mode 100644 index 3676ac9f8..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_05_simple_harmonic_mot_trail/_3_05_simple_harmonic_mot_trail.pde +++ /dev/null @@ -1,20 +0,0 @@ -void setup() { - size(800,200); - background(255); -} - -void draw() { - noStroke(); - fill(255,5); - rect(0,0,width,height); - float period = 120; - float amplitude = 300; - // Calculating horizontal location according to formula for simple harmonic motion - float x = amplitude * cos(TWO_PI * frameCount / period); - stroke(0); - strokeWeight(2); - fill(127); - translate(width/2,height/2); - line(0,0,x,0); - ellipse(x,0,48,48); -} diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_05_simple_harmonic_motion/_3_05_simple_harmonic_motion.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_05_simple_harmonic_motion/_3_05_simple_harmonic_motion.pde deleted file mode 100644 index e03a0cb6b..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_05_simple_harmonic_motion/_3_05_simple_harmonic_motion.pde +++ /dev/null @@ -1,18 +0,0 @@ -void setup() { - size(800,200); -} - -void draw() { - background(255); - - float period = 120; - float amplitude = 300; - // Calculating horizontal location according to formula for simple harmonic motion - float x = amplitude * cos(TWO_PI * frameCount / period); - stroke(0); - strokeWeight(2); - fill(127); - translate(width/2,height/2); - line(0,0,x,0); - ellipse(x,0,48,48); -} diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_06_simple_harmonic_motion/_3_06_simple_harmonic_motion.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_06_simple_harmonic_motion/_3_06_simple_harmonic_motion.pde deleted file mode 100644 index 1ce795598..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_06_simple_harmonic_motion/_3_06_simple_harmonic_motion.pde +++ /dev/null @@ -1,23 +0,0 @@ -float angle = 0; -float aVelocity = 0.03; - -void setup() { - size(640,360); - - smooth(); -} - -void draw() { - background(255); - - float amplitude = 300; - float x = amplitude * cos(angle); - angle += aVelocity; - - ellipseMode(CENTER); - stroke(0); - fill(175); - translate(width/2,height/2); - line(0,0,x,0); - ellipse(x,0,20,20); -} diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_07_oscillating_objects/Oscillator.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_07_oscillating_objects/Oscillator.pde deleted file mode 100644 index 3377681b6..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_07_oscillating_objects/Oscillator.pde +++ /dev/null @@ -1,33 +0,0 @@ -class Oscillator { - - PVector angle; - PVector velocity; - PVector amplitude; - - Oscillator() { - angle = new PVector(); - velocity = new PVector(random(-0.05, 0.05), random(-0.05, 0.05)); - amplitude = new PVector(random(20,width/2), random(20,height/2)); - } - - void oscillate() { - angle.add(velocity); - } - - void display() { - - float x = sin(angle.x)*amplitude.x; - float y = sin(angle.y)*amplitude.y; - - pushMatrix(); - translate(width/2, height/2); - stroke(0); - strokeWeight(2); - fill(127,127); - line(0, 0, x, y); - ellipse(x, y, 32, 32); - popMatrix(); - } -} - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_07_oscillating_objects/_3_07_oscillating_objects.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_07_oscillating_objects/_3_07_oscillating_objects.pde deleted file mode 100644 index 5f9403c8d..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_07_oscillating_objects/_3_07_oscillating_objects.pde +++ /dev/null @@ -1,33 +0,0 @@ -// Learning Processing -// Daniel Shiffman -// http://www.learningprocessing.com - -// Exercise 13-6: Encapsulate Example 13-6 into an Oscillator object. Create an array -// of Oscillators, each moving at diff erent rates along the x and y axes. Here is some code for the -// Oscillator class to help you get started. - -// An array of objects -Oscillator[] oscillators = new Oscillator[10]; - -void setup() { - size(800,200); - smooth(); - // Initialize all objects - for (int i = 0; i < oscillators.length; i++) { - oscillators[i] = new Oscillator(); - } - background(255); -} - -void draw() { - background(255); - // Run all objects - for (int i = 0; i < oscillators.length; i++) { - oscillators[i].oscillate(); - oscillators[i].display(); - } -} - - - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_07_oscillating_objects_trail/Oscillator.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_07_oscillating_objects_trail/Oscillator.pde deleted file mode 100644 index 3377681b6..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_07_oscillating_objects_trail/Oscillator.pde +++ /dev/null @@ -1,33 +0,0 @@ -class Oscillator { - - PVector angle; - PVector velocity; - PVector amplitude; - - Oscillator() { - angle = new PVector(); - velocity = new PVector(random(-0.05, 0.05), random(-0.05, 0.05)); - amplitude = new PVector(random(20,width/2), random(20,height/2)); - } - - void oscillate() { - angle.add(velocity); - } - - void display() { - - float x = sin(angle.x)*amplitude.x; - float y = sin(angle.y)*amplitude.y; - - pushMatrix(); - translate(width/2, height/2); - stroke(0); - strokeWeight(2); - fill(127,127); - line(0, 0, x, y); - ellipse(x, y, 32, 32); - popMatrix(); - } -} - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_07_oscillating_objects_trail/_3_07_oscillating_objects_trail.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_07_oscillating_objects_trail/_3_07_oscillating_objects_trail.pde deleted file mode 100644 index 2d8c739b3..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_07_oscillating_objects_trail/_3_07_oscillating_objects_trail.pde +++ /dev/null @@ -1,36 +0,0 @@ -// Learning Processing -// Daniel Shiffman -// http://www.learningprocessing.com - -// Exercise 13-6: Encapsulate Example 13-6 into an Oscillator object. Create an array -// of Oscillators, each moving at diff erent rates along the x and y axes. Here is some code for the -// Oscillator class to help you get started. - -// An array of objects -Oscillator[] oscillators = new Oscillator[10]; - -void setup() { - size(800,200); - smooth(); - // Initialize all objects - for (int i = 0; i < oscillators.length; i++) { - oscillators[i] = new Oscillator(); - } - background(255); -} - -void draw() { - rectMode(CORNER); - noStroke(); - fill(255,10); - rect(0,0,width,height); - // Run all objects - for (int i = 0; i < oscillators.length; i++) { - oscillators[i].oscillate(); - oscillators[i].display(); - } -} - - - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_08_static_wave_lines/_3_08_static_wave_lines.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_08_static_wave_lines/_3_08_static_wave_lines.pde deleted file mode 100644 index 91a3d91d4..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_08_static_wave_lines/_3_08_static_wave_lines.pde +++ /dev/null @@ -1,19 +0,0 @@ -float angle = 0; -float angleVel = 0.1; - -size(800,200); -background(255); -smooth(); - -stroke(0); -strokeWeight(2); -noFill(); - -beginShape(); -for (int x = 0; x <= width; x += 5) { - float y = map(sin(angle),-1,1,0,height); - vertex(x,y); - angle +=angleVel; -} -endShape(); - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_exercise_additive_wave/_3_09_exercise_additive_wave.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_exercise_additive_wave/_3_09_exercise_additive_wave.pde deleted file mode 100644 index 888f4b142..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_exercise_additive_wave/_3_09_exercise_additive_wave.pde +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Additive Wave - * by Daniel Shiffman. - * - * Create a more complex wave by adding two waves together. - */ - -// Maybe better for this answer to be OOP??? - -int xspacing = 8; // How far apart should each horizontal location be spaced -int w; // Width of entire wave -int maxwaves = 5; // total # of waves to add together - -float theta = 0.0; -float[] amplitude = new float[maxwaves]; // Height of wave -float[] dx = new float[maxwaves]; // Value for incrementing X, to be calculated as a function of period and xspacing -float[] yvalues; // Using an array to store height values for the wave (not entirely necessary) - -void setup() { - size(640,360); - colorMode(RGB, 255, 255, 255, 100); - smooth(); - w = width + 16; - - for (int i = 0; i < maxwaves; i++) { - amplitude[i] = random(10,30); - float period = random(100,300); // How many pixels before the wave repeats - dx[i] = (TWO_PI / period) * xspacing; - } - - yvalues = new float[w/xspacing]; -} - -void draw() { - background(0); - calcWave(); - renderWave(); -} - -void calcWave() { - // Increment theta (try different values for 'angular velocity' here - theta += 0.02; - - // Set all height values to zero - for (int i = 0; i < yvalues.length; i++) { - yvalues[i] = 0; - } - - // Accumulate wave height values - for (int j = 0; j < maxwaves; j++) { - float x = theta; - for (int i = 0; i < yvalues.length; i++) { - // Every other wave is cosine instead of sine - if (j % 2 == 0) yvalues[i] += sin(x)*amplitude[j]; - else yvalues[i] += cos(x)*amplitude[j]; - x+=dx[j]; - } - } -} - -void renderWave() { - // A simple way to draw the wave with an ellipse at each location - noStroke(); - fill(255,50); - ellipseMode(CENTER); - for (int x = 0; x < yvalues.length; x++) { - ellipse(x*xspacing,height/2+yvalues[x],16,16); - } -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_wave/_3_09_wave.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_wave/_3_09_wave.pde deleted file mode 100644 index 5eb61b28b..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_wave/_3_09_wave.pde +++ /dev/null @@ -1,28 +0,0 @@ - -float startAngle = 0; -float angleVel = 0.23; - -void setup() { - size(800,200); - smooth(); -} - -void draw() { - background(255); - - startAngle += 0.015; - float angle = startAngle; - - for (int x = 0; x <= width; x += 24) { - float y = map(sin(angle),-1,1,0,height); - stroke(0); - fill(0,50); - strokeWeight(2); - ellipse(x,y,48,48); - angle += angleVel; - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_wave_a/_3_09_wave_a.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_wave_a/_3_09_wave_a.pde deleted file mode 100644 index b4a96efba..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_wave_a/_3_09_wave_a.pde +++ /dev/null @@ -1,28 +0,0 @@ - -float startAngle = 0; -float angleVel = 0.05; - -void setup() { - size(250,200); - smooth(); -} - -void draw() { - background(255); - - startAngle += 0.015; - float angle = startAngle; - - for (int x = 0; x <= width; x += 24) { - float y = map(sin(angle),-1,1,0,height); - stroke(0); - fill(0,50); - strokeWeight(2); - ellipse(x,y,48,48); - angle += angleVel; - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_wave_b/_3_09_wave_b.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_wave_b/_3_09_wave_b.pde deleted file mode 100644 index 9749647db..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_wave_b/_3_09_wave_b.pde +++ /dev/null @@ -1,28 +0,0 @@ - -float startAngle = 0; -float angleVel = 0.2; - -void setup() { - size(250,200); - smooth(); -} - -void draw() { - background(255); - - startAngle += 0.015; - float angle = startAngle; - - for (int x = 0; x <= width; x += 24) { - float y = map(sin(angle),-1,1,0,height); - stroke(0); - fill(0,50); - strokeWeight(2); - ellipse(x,y,48,48); - angle += angleVel; - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_wave_c/_3_09_wave_c.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_wave_c/_3_09_wave_c.pde deleted file mode 100644 index 74349d4f4..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_09_wave_c/_3_09_wave_c.pde +++ /dev/null @@ -1,28 +0,0 @@ - -float startAngle = 0; -float angleVel = 0.4; - -void setup() { - size(250,200); - smooth(); -} - -void draw() { - background(255); - - startAngle += 0.015; - float angle = startAngle; - - for (int x = 0; x <= width; x += 24) { - float y = map(sin(angle),-1,1,0,height); - stroke(0); - fill(0,50); - strokeWeight(2); - ellipse(x,y,48,48); - angle += angleVel; - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_10_PendulumExample/Pendulum.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_10_PendulumExample/Pendulum.pde deleted file mode 100644 index 260f793b2..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_10_PendulumExample/Pendulum.pde +++ /dev/null @@ -1,95 +0,0 @@ -// Pendulum -// Daniel Shiffman - -// A Simple Pendulum Class -// Includes functionality for user can click and drag the pendulum - -class Pendulum { - - PVector location; // Location of pendulum ball - PVector origin; // Location of arm origin - float r; // Length of arm - float angle; // Pendulum arm angle - float aVelocity; // Angle velocity - float aAcceleration; // Angle acceleration - - float ballr; // Ball radius - float damping; // Arbitary damping amount - - boolean dragging = false; - - // This constructor could be improved to allow a greater variety of pendulums - Pendulum(PVector origin_, float r_) { - // Fill all variables - origin = origin_.get(); - location = new PVector(); - r = r_; - angle = PI/4; - - aVelocity = 0.0; - aAcceleration = 0.0; - damping = 0.995; // Arbitrary damping - ballr = 48.0; // Arbitrary ball radius - } - - void go() { - update(); - drag(); //for user interaction - display(); - } - - // Function to update location - void update() { - // As long as we aren't dragging the pendulum, let it swing! - if (!dragging) { - float gravity = 0.4; // Arbitrary constant - aAcceleration = (-1 * gravity / r) * sin(angle); // Calculate acceleration (see: http://www.myphysicslab.com/pendulum1.html) - aVelocity += aAcceleration; // Increment velocity - aVelocity *= damping; // Arbitrary damping - angle += aVelocity; // Increment angle - } - } - - void display() { - location.set(r*sin(angle), r*cos(angle), 0); // Polar to cartesian conversion - location.add(origin); // Make sure the location is relative to the pendulum's origin - - stroke(0); - strokeWeight(2); - // Draw the arm - line(origin.x, origin.y, location.x, location.y); - ellipseMode(CENTER); - fill(175); - if (dragging) fill(0); - // Draw the ball - ellipse(location.x, location.y, ballr, ballr); - } - - - // The methods below are for mouse interaction - - // This checks to see if we clicked on the pendulum ball - void clicked(int mx, int my) { - float d = dist(mx, my, location.x, location.y); - if (d < ballr) { - dragging = true; - } - } - - // This tells us we are not longer clicking on the ball - void stopDragging() { - aVelocity = 0; // No velocity once you let go - dragging = false; - } - - void drag() { - // If we are draging the ball, we calculate the angle between the - // pendulum origin and mouse location - // we assign that angle to the pendulum - if (dragging) { - PVector diff = PVector.sub(origin, new PVector(mouseX, mouseY)); // Difference between 2 points - angle = atan2(-1*diff.y, diff.x) - radians(90); // Angle relative to vertical axis - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_10_PendulumExample/_3_10_PendulumExample.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_10_PendulumExample/_3_10_PendulumExample.pde deleted file mode 100644 index 2a455823a..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_10_PendulumExample/_3_10_PendulumExample.pde +++ /dev/null @@ -1,43 +0,0 @@ -// Pendulum -// Daniel Shiffman - -// A simple pendulum simulation -// Given a pendulum with an angle theta (0 being the pendulum at rest) and a radius r -// we can use sine to calculate the angular component of the gravitational force. - -// Gravity Force = Mass * Gravitational Constant; -// Pendulum Force = Gravity Force * sine(theta) -// Angular Acceleration = Pendulum Force / Mass = gravitational acceleration * sine(theta); - -// Note this is an ideal world scenario with no tension in the -// pendulum arm, a more realistic formula might be: -// Angular Acceleration = (g / R) * sine(theta) - -// For a more substantial explanation, visit: -// http://www.myphysicslab.com/pendulum1.html - -Pendulum p; - -void setup() { - size(800,200); - smooth(); - - // Make a new Pendulum with an origin location and armlength - p = new Pendulum(new PVector(width/2,0),175); - -} - -void draw() { - - background(255); - p.go(); -} - -void mousePressed() { - p.clicked(mouseX,mouseY); -} - -void mouseReleased() { - p.stopDragging(); -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_10_PendulumExampleSimplified/Pendulum.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_10_PendulumExampleSimplified/Pendulum.pde deleted file mode 100644 index 72d1e8cf9..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_10_PendulumExampleSimplified/Pendulum.pde +++ /dev/null @@ -1,61 +0,0 @@ -// Pendulum -// Daniel Shiffman - -// A Simple Pendulum Class -// Includes functionality for user can click and drag the pendulum - -class Pendulum { - - PVector location; // Location of pendulum ball - PVector origin; // Location of arm origin - float r; // Length of arm - float angle; // Pendulum arm angle - float aVelocity; // Angle velocity - float aAcceleration; // Angle acceleration - float damping; // Arbitary damping amount - - // This constructor could be improved to allow a greater variety of pendulums - Pendulum(PVector origin_, float r_) { - // Fill all variables - origin = origin_.get(); - location = new PVector(); - r = r_; - angle = PI/4; - - aVelocity = 0.0; - aAcceleration = 0.0; - damping = 0.995; // Arbitrary damping - } - - void go() { - update(); - display(); - } - - // Function to update location - void update() { - float gravity = 0.4; // Arbitrary constant - aAcceleration = (-1 * gravity / r) * sin(angle); // Calculate acceleration (see: http://www.myphysicslab.com/pendulum1.html) - aVelocity += aAcceleration; // Increment velocity - aVelocity *= damping; // Arbitrary damping - angle += aVelocity; // Increment angle - } - - void display() { - location.set(r*sin(angle), r*cos(angle), 0); // Polar to cartesian conversion - location.add(origin); // Make sure the location is relative to the pendulum's origin - - stroke(0); - strokeWeight(2); - // Draw the arm - line(origin.x, origin.y, location.x, location.y); - ellipseMode(CENTER); - fill(175); - // Draw the ball - ellipse(location.x, location.y, 48, 48); - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_10_PendulumExampleSimplified/_3_10_PendulumExampleSimplified.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_10_PendulumExampleSimplified/_3_10_PendulumExampleSimplified.pde deleted file mode 100644 index b40d7fea8..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_10_PendulumExampleSimplified/_3_10_PendulumExampleSimplified.pde +++ /dev/null @@ -1,34 +0,0 @@ -// Pendulum -// Daniel Shiffman - -// A simple pendulum simulation -// Given a pendulum with an angle theta (0 being the pendulum at rest) and a radius r -// we can use sine to calculate the angular component of the gravitational force. - -// Gravity Force = Mass * Gravitational Constant; -// Pendulum Force = Gravity Force * sine(theta) -// Angular Acceleration = Pendulum Force / Mass = Gravitational Constant * sine(theta); - -// Note this is an ideal world scenario with no tension in the -// pendulum arm, a more realistic formula might be: -// Angular Acceleration = (G / R) * sine(theta) - -// For a more substantial explanation, visit: -// http://www.myphysicslab.com/pendulum1.html - -Pendulum p; - -void setup() { - size(800,200); - smooth(); - - // Make a new Pendulum with an origin location and armlength - p = new Pendulum(new PVector(width/2,0),175); - -} - -void draw() { - background(255); - p.go(); -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/Mover.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/Mover.pde deleted file mode 100644 index b25dcda65..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/Mover.pde +++ /dev/null @@ -1,78 +0,0 @@ -// Nature of Code 2011 -// Daniel Shiffman -// Chapter 3: Oscillation - -// Bob class, just like our regular Mover (location, velocity, acceleration, mass) - -class Bob { - PVector location; - PVector velocity; - PVector acceleration; - float mass = 24; - - // Arbitrary damping to simulate friction / drag - float damping = 0.98; - - // For mouse interaction - PVector dragOffset; - boolean dragging = false; - - // Constructor - Bob(float x, float y) { - location = new PVector(x,y); - velocity = new PVector(); - acceleration = new PVector(); - dragOffset = new PVector(); - } - - // Standard Euler integration - void update() { - velocity.add(acceleration); - velocity.mult(damping); - location.add(velocity); - acceleration.mult(0); - } - - // Newton's law: F = M * A - void applyForce(PVector force) { - PVector f = force.get(); - f.div(mass); - acceleration.add(f); - } - - - // Draw the bob - void display() { - stroke(0); - strokeWeight(2); - fill(175); - if (dragging) { - fill(50); - } - ellipse(location.x,location.y,mass*2,mass*2); - } - - // The methods below are for mouse interaction - - // This checks to see if we clicked on the mover - void clicked(int mx, int my) { - float d = dist(mx,my,location.x,location.y); - if (d < mass) { - dragging = true; - dragOffset.x = location.x-mx; - dragOffset.y = location.y-my; - } - } - - void stopDragging() { - dragging = false; - } - - void drag(int mx, int my) { - if (dragging) { - location.x = mx + dragOffset.x; - location.y = my + dragOffset.y; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/Spring.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/Spring.pde deleted file mode 100644 index 565fbb307..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/Spring.pde +++ /dev/null @@ -1,75 +0,0 @@ -// Nature of Code 2011 -// Daniel Shiffman -// Chapter 3: Oscillation - -// Class to describe an anchor point that can connect to "Bob" objects via a spring -// Thank you: http://www.myphysicslab.com/spring2d.html - -class Spring { - - // Location - PVector anchor; - - // Rest length and spring constant - float len; - float k = 0.2; - - // Constructor - Spring(float x, float y, int l) { - anchor = new PVector(x, y); - len = l; - } - - // Calculate spring force - void connect(Bob b) { - // Vector pointing from anchor to bob location - PVector force = PVector.sub(b.location, anchor); - // What is distance - float d = force.mag(); - // Stretch is difference between current distance and rest length - float stretch = d - len; - - // Calculate force according to Hooke's Law - // F = k * stretch - force.normalize(); - force.mult(-1 * k * stretch); - b.applyForce(force); - } - - // Constrain the distance between bob and anchor between min and max - void constrainLength(Bob b, float minlen, float maxlen) { - PVector dir = PVector.sub(b.location, anchor); - float d = dir.mag(); - // Is it too short? - if (d < minlen) { - dir.normalize(); - dir.mult(minlen); - // Reset location and stop from moving (not realistic physics) - b.location = PVector.add(anchor, dir); - b.velocity.mult(0); - // Is it too long? - } - else if (d > maxlen) { - dir.normalize(); - dir.mult(maxlen); - // Reset location and stop from moving (not realistic physics) - b.location = PVector.add(anchor, dir); - b.velocity.mult(0); - } - } - - void display() { - stroke(0); - fill(175); - strokeWeight(2); - rectMode(CENTER); - rect(anchor.x, anchor.y, 10, 10); - } - - void displayLine(Bob b) { - strokeWeight(2); - stroke(0); - line(b.location.x, b.location.y, anchor.x, anchor.y); - } -} - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/_3_11_spring.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/_3_11_spring.pde deleted file mode 100644 index 57c8c7212..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/_3_11_spring.pde +++ /dev/null @@ -1,61 +0,0 @@ -// Nature of Code 2011 -// Daniel Shiffman -// Chapter 3: Oscillation -// Mover attached to spring connection -// PVector -// http://www.shiffman.net - - -// Mover object -Bob bob; - -// Spring object -Spring spring; - -void setup() { - size(800,200); - smooth(); - // Create objects at starting location - // Note third argument in Spring constructor is "rest length" - spring = new Spring(width/2,10,100); - bob = new Bob(width/2,100); - -} - -void draw() { - background(255); - // Apply a gravity force to the bob - PVector gravity = new PVector(0,2); - bob.applyForce(gravity); - - // Connect the bob to the spring (this calculates the force) - spring.connect(bob); - // Constrain spring distance between min and max - spring.constrainLength(bob,30,200); - - // Update bob - bob.update(); - // If it's being dragged - bob.drag(mouseX,mouseY); - - // Draw everything - spring.displayLine(bob); // Draw a line between spring and bob - bob.display(); - spring.display(); - - fill(0); - text("click on bob to drag",10,height-5); -} - - -// For mouse interaction with bob - -void mousePressed() { - bob.clicked(mouseX,mouseY); -} - -void mouseReleased() { - bob.stopDragging(); -} - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/sketch.properties b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/sketch.properties deleted file mode 100644 index b3cbe600e..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/sketch.properties +++ /dev/null @@ -1,2 +0,0 @@ -mode.id=processing.mode.java.JavaMode -mode=Standard diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/web-export/_3_11_spring.pde b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/web-export/_3_11_spring.pde deleted file mode 100644 index 1cdd11276..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/web-export/_3_11_spring.pde +++ /dev/null @@ -1,215 +0,0 @@ -// Nature of Code 2011 -// Daniel Shiffman -// Chapter 3: Oscillation -// Mover attached to spring connection -// PVector -// http://www.shiffman.net - - -// Mover object -Bob bob; - -// Spring object -Spring spring; - -void setup() { - size(800,200); - smooth(); - // Create objects at starting location - // Note third argument in Spring constructor is "rest length" - spring = new Spring(width/2,10,100); - bob = new Bob(width/2,100); - -} - -void draw() { - background(255); - // Apply a gravity force to the bob - PVector gravity = new PVector(0,1); - bob.applyForce(gravity); - - // Connect the bob to the spring (this calculates the force) - spring.connect(bob); - // Constrain spring distance between min and max - spring.constrainLength(bob,30,200); - - // Update bob - bob.update(); - // If it's being dragged - bob.drag(mouseX,mouseY); - - // Draw everything - spring.displayLine(bob); // Draw a line between spring and bob - bob.display(); - spring.display(); - - fill(0); - text("click on bob to drag",10,height-5); -} - - -// For mouse interaction with bob - -void mousePressed() { - bob.clicked(mouseX,mouseY); -} - -void mouseReleased() { - bob.stopDragging(); -} - - -// Nature of Code 2011 -// Daniel Shiffman -// Chapter 3: Oscillation - -// Bob class, just like our regular Mover (location, velocity, acceleration, mass) - -class Bob { - PVector location; - PVector velocity; - PVector acceleration; - float mass = 24; - - // Arbitrary damping to simulate friction / drag - float damping = 0.98; - - // For mouse interaction - PVector dragOffset; - boolean dragging = false; - - // Constructor - Bob(float x, float y) { - location = new PVector(x,y); - velocity = new PVector(); - acceleration = new PVector(); - dragOffset = new PVector(); - } - - // Standard Euler integration - void update() { - velocity.add(acceleration); - velocity.mult(damping); - location.add(velocity); - acceleration.mult(0); - } - - // Newton's law: F = M * A - void applyForce(PVector force) { - PVector f = force.get(); - f.div(mass); - acceleration.add(f); - } - - - // Draw the bob - void display() { - stroke(0); - strokeWeight(2); - fill(175); - if (dragging) { - fill(50); - } - ellipse(location.x,location.y,mass*2,mass*2); - } - - // The methods below are for mouse interaction - - // This checks to see if we clicked on the mover - void clicked(int mx, int my) { - float d = dist(mx,my,location.x,location.y); - if (d < mass) { - dragging = true; - dragOffset.x = location.x-mx; - dragOffset.y = location.y-my; - } - } - - void stopDragging() { - dragging = false; - } - - void drag(int mx, int my) { - if (dragging) { - location.x = mx + dragOffset.x; - location.y = my + dragOffset.y; - } - } -} - -// Nature of Code 2011 -// Daniel Shiffman -// Chapter 3: Oscillation - -// Class to describe an anchor point that can connect to "Bob" objects via a spring -// Thank you: http://www.myphysicslab.com/spring2d.html - -class Spring { - - // Location - PVector anchor; - - // Rest length and spring constant - float len; - float k = 0.1; - - // Constructor - Spring(float x, float y, int l) { - anchor = new PVector(x, y); - len = l; - } - - // Calculate spring force - void connect(Bob b) { - // Vector pointing from anchor to bob location - PVector force = PVector.sub(b.location, anchor); - // What is distance - float d = force.mag(); - // Stretch is difference between current distance and rest length - float stretch = d - len; - - // Calculate force according to Hooke's Law - // F = k * stretch - force.normalize(); - force.mult(-1 * k * stretch); - b.applyForce(force); - } - - // Constrain the distance between bob and anchor between min and max - void constrainLength(Bob b, float minlen, float maxlen) { - PVector dir = PVector.sub(b.location, anchor); - float d = dir.mag(); - // Is it too short? - if (d < minlen) { - dir.normalize(); - dir.mult(minlen); - // Reset location and stop from moving (not realistic physics) - b.location = PVector.add(anchor, dir); - b.velocity.mult(0); - // Is it too long? - } - else if (d > maxlen) { - dir.normalize(); - dir.mult(maxlen); - // Reset location and stop from moving (not realistic physics) - b.location = PVector.add(anchor, dir); - b.velocity.mult(0); - } - } - - void display() { - stroke(0); - fill(175); - strokeWeight(2); - rectMode(CENTER); - rect(anchor.x, anchor.y, 10, 10); - } - - void displayLine(Bob b) { - strokeWeight(2); - stroke(0); - line(b.location.x, b.location.y, anchor.x, anchor.y); - } -} - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/web-export/processing.js b/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/web-export/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/NOC_3_11_spring/web-export/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/OOPWaveParticles/OOPWaveParticles.pde b/java/examples/Books/Nature of Code/chp3_oscillation/OOPWaveParticles/OOPWaveParticles.pde deleted file mode 100644 index 9cf9e3b3d..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/OOPWaveParticles/OOPWaveParticles.pde +++ /dev/null @@ -1,31 +0,0 @@ -// Sine Wave -// Daniel Shiffman - - -// Two wave objects -Wave wave0; -Wave wave1; - -void setup() { - size(640,360); - smooth(); - // Initialize a wave with starting point, width, amplitude, and period - wave0 = new Wave(new PVector(200,75),100,20,500); - wave1 = new Wave(new PVector(150,250),300,40,220); - -} - -void draw() { - background(255); - - // Update and display waves - wave0.calculate(); - wave0.display(); - - wave1.calculate(); - wave1.display(); - - -} - - diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/OOPWaveParticles/Particle.pde b/java/examples/Books/Nature of Code/chp3_oscillation/OOPWaveParticles/Particle.pde deleted file mode 100644 index ca6d677d2..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/OOPWaveParticles/Particle.pde +++ /dev/null @@ -1,20 +0,0 @@ - -class Particle { - PVector location; - - Particle() { - location = new PVector(); - } - - void setLocation(float x, float y) { - location.x = x; - location.y = y; - } - - void display() { - fill(random(255)); - ellipse(location.x,location.y,16,16); - } - - -} diff --git a/java/examples/Books/Nature of Code/chp3_oscillation/OOPWaveParticles/Wave.pde b/java/examples/Books/Nature of Code/chp3_oscillation/OOPWaveParticles/Wave.pde deleted file mode 100644 index cd54393be..000000000 --- a/java/examples/Books/Nature of Code/chp3_oscillation/OOPWaveParticles/Wave.pde +++ /dev/null @@ -1,52 +0,0 @@ -class Wave { - - int xspacing = 8; // How far apart should each horizontal location be spaced - int w; // Width of entire wave - - PVector origin; // Where does the wave's first point start - float theta = 0.0; // Start angle at 0 - float amplitude; // Height of wave - float period; // How many pixels before the wave repeats - float dx; // Value for incrementing X, to be calculated as a function of period and xspacing - //float[] yvalues; // Using an array to store height values for the wave (not entirely necessary) - Particle[] particles; - - Wave(PVector o, int w_, float a, float p) { - origin = o.get(); - w = w_; - period = p; - amplitude = a; - dx = (TWO_PI / period) * xspacing; - particles = new Particle[w/xspacing]; - for (int i = 0; i < particles.length; i++) { - particles[i] = new Particle(); - } - } - - - void calculate() { - // Increment theta (try different values for 'angular velocity' here - theta += 0.02; - - // For every x value, calculate a y value with sine function - float x = theta; - for (int i = 0; i < particles.length; i++) { - particles[i].setLocation(origin.x+i*xspacing,origin.y+sin(x)*amplitude); - x+=dx; - } - } - - void manipulate() { - // Loop through the array of particles and check stuff regarding the mouse - - } - - void display() { - - // A simple way to draw the wave with an ellipse at each location - for (int i = 0; i < particles.length; i++) { - particles[i].display(); - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp4_systems/CircleVsBlob/CircleVsBlob.pde b/java/examples/Books/Nature of Code/chp4_systems/CircleVsBlob/CircleVsBlob.pde deleted file mode 100644 index d552e3d74..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/CircleVsBlob/CircleVsBlob.pde +++ /dev/null @@ -1,28 +0,0 @@ -// Smoke Particle System -// Daniel Shiffman - -// A basic smoke effect using a particle system -// Each particle is rendered as an alpha masked image - - -void setup() { - size(200,200); - smooth(); - PImage img = loadImage("texture.png"); - background(0); - image(img,0,0,width,height); - save("blob.tif"); - - background(0); - fill(255); - noStroke(); - ellipse(100,100,width,height); - save("circle.tif"); -} - -void draw() { - - -} - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/CircleVsBlob/blob.tif b/java/examples/Books/Nature of Code/chp4_systems/CircleVsBlob/blob.tif deleted file mode 100644 index 62b3058e45db3d32555fa9fd3be07d2ad10481bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120768 zcmeF)3A`o!R^Ih{xrF&%z(9xuqlt)$sK^vGfZzqLU1stN{1Spdl z1yn#m1yMo3h$IBiIDsh6h)m8XY7jLJAHP+ zThDr`_CD|Z#7}(92fpStuX(4}yz^`Rzt_CIz1RBxZS%VQkKb?qwafn7?fcumz3H{@ zaP#xG^P2a(eedgD^V;{m`MFoU_SY@%eV?1xy!I!5ulH}~-2U&?cr^oW#tgjnQoP+M zUiY+k`#pZmDc<41c*i~7X^(ea;$7~>yYBIBr+EF{c*7gs@b0(q9;bNE`{NI}6upptTW)82sKcpH+Yc(@Y^(W+h2sw{ z5p?-y$9KNn+dU1d*S*SBjJ?X$Wu*3>zRDFyu8^x=`>I|+8vvcb$YM&dM`h*eIR`BDpAsBOv(|1c zaqzTVkwDO|drsj{>ycyZK$;6U)4t+&Sk5fdst;+AD?d53VQ5XmPPPMVwud{!vx21? z=jtDRa?xTP*t-TQhwY39fjVF3ETNrQ;4InBeH5M5Y0`U0`%rXIi_Xlv&)xX-d-z#9 zv;9M_hSTg9rk{bUT)EWGBjU1QDFS*B8|`udZhw+FMbqk)#L{pmn==vptUAbs`DO_zs8xg>a|Y8 zgTK1SL(H5F)%uewxpKPo?Cqbq8kS}`BTy?>l2DgTW~LwSQ>TGyt%cI8l{&DLl2r6F zEq~bE_>GSZhdCTP@XoMxJr}8K6_#`8nixaZ3fQD*k~XSUR%2}F8pd8IR~K#h`oj?Q zla`$)jOeX8ll`A=)UXHOdSN&ww z2a2KA6T`qt$Tj=kctEH_&5_$Vh}C)}>(#DMS)uHYld;8m<*p6#h@#|_2QkK1^V7=Tf`!m8dgRmXE8^rFNtUOOv{K)=(Ih zq*}snKJjnl0ISUWQr)kT4(SnZs-TIotj?vt-GNGn1Y_g@KD(ppbz>WKd^ludcocIZGT&l zbe2K4v$q}8+i{()dD>wVtZ^A#whhMvSLJFKd-DRIoEz z2d?g$fCu=y>@!z2&MZ8rrrpZVXjD1Wq*6NRE!zjE)B;qExm69;YEFrjd#XQR91!~B zuZY82I+P#IF~e+S_@aU}D{Bhd0JEYIu9mE)LTlHp8{xXh)tHL%JgPO_eUYosYVNFn ztrb7()ywCK*v>*`Y1eQyIF-N#U%9m%qS~pu&s-%1t43ARgE|cxD@T9A)v>;-{W)Me zF*X>-*h-fxY%-p?YH71xofTRVB1+D~Tm=}qCjV6gSF6#QnHW?D;d*ggtw&z9aaGH+ zUR}c#(I!?S<7Meeu1foikHl(5OyjQ#u8MKyDjp6f{fSq^;Vu4p5wlcl(6ZB24P9Mo z)6gmc%(|}ODs3-swlXQ7In~)-bn*{#HLA6i7zTNG8nwoG#$EFhM|dh%WD{41k*z5X zdNt#3g!&>^BU3e|Ce^Cbwg;T1%`dvCh?<%zF&Q~j9}ff32j50Nx&7Pm&%?jY+s``= zepWEoGpMh0O;e2HTG67_nSn8x@}mdGh>mvUvU08H8r2%%QkOGVqgo>o%KE&xLQzbv z+XGiKd`C8es!O%aR=N0f>RH{{O=Zg^CzfpGO7;#@PxHo)b{6u#%2B0JtYK!9WC}fG ze8`7<$cHZRVYl(&xA74l@e#k}HvZ&2`rEqSPrULFj&Xaun?IdS{7HMvHO%GB=mh+b zX2*(}k3*Ur3%@9016#vUG83+*K#X0aOLeC4b6i7IJ7=ztfV7ndoUGc_{#mac&DG#E zGBqs4CeRrz)$&n7SqC=FbBgD@A|G5^=TC zweH`N_*)J~3$H-l5!*I%d0lOE<;2=1XrWaH*~)RrQ?oP$dKCvc@qm28wDoNTM9`YQC9 ztD(XUT85@Sb&2`m?5w2OA0XGGrCOQW<9t0S=sMbtIJ2@_B zf$CYgQr4MGt9A_)b{?l!bA-onHA=M(!PTW(_;8hNXb7(NdOEb(H$y>^6RUyB&PA?9 zBC2fau}aD?utI{I-+GD#u_wF3*zBywad77f{D_RhM-RUev4S$QAsCB|G6XJN@;dUd{M(h35%4T!CsN`T$iv!FEKx z)X5~S*3Ok`TuFXYqfSq()N9qKRhqgn^OimOpA!j*PG>o5w(9ybs{C04y^ ze^nS@j1OO3*4bZO$yFzvtt&Zm<;vj{QQE|EQmR#@iB-3I$y8zR-N)6+So>$LqI5le zI7Rh9PNs^w093IwYe}grv-P$Os&Jawmq5X(M+ee4EXlBJ6DUNDK-KaJbXKQoIvS$T zias#J$>8%bxACzb`>}ueb>Wr8?OSjDoMSo{-d56F!$s1j9g;GDt&`EJb(82;u`Yv| zEY*Fs^`kUGOXMpsR;p)A*f9|GyBdiZF1H1|`Kr9iD)Cx(`&V)`A~rh+TmzF1<$xni zc4CP@oi)lucC{|s#jk6LD9a?&qE!!3({z#}UFFSod{iI}OOme;`aR!bxX^(!MJdn9 zkHSYn;JopTZ~VBA`?!z)_>cdD+xTru{2BK|FX^OP?dEp2F40lx#Hn;tElPCM8hgK$>@T_sW&Jq)W>C09Y!-Bw~X zIAwJbtGHUBB2a6X zP&NA+9NIiLPNP88l(9XFl`5}#qV%gk#Rf?J>?`5`-HO(L>Rh2UbYX0+D!@W(OrRah z8Oa*eqF3FatOIf7Dzx-wDYZ2VB-wzF_Cd=uq*ucg1t_MJcJf-Poabp28dacrE?kYd znjve)xyIwo#l(C{MPpsIi(g&3b!DqouB=@ighmteTyl)Rh#IKmv!1Pg^XF;Q^!PgU zX5u6iw(H1K^ci7bfCq^FoFzW-6F>3Ky)L|Rq60Y8@D^z?HX?>J*E8DXQeg(LG}bCa z@|9{OTxplKTItem5+z;eDrlD+CjPc(w4%!#Q5~U7g_4~u)|FhX)9^eK`$?~9dah8# ztrLkeR4xhguC3@&UHr_xf$CtWh9wCRk|RqAR9%@-2bIJMNfx6{Gw+h7inX#dauiEZ z1b|?Ooj>n3{`}kcq)+;!zu+0eTZ992u%Xhq4y3t;7)v%&GgqF7rC`WTucjvN(t^lJ6Gjx&*g|6ZkRV(2N7~A+cZ|4Q!vVd6W(19jC3%~vC#93#pwiSc=2EAF zC`Ht&MX{vrF%UR^;cfgyOMLPtfAU{)Mf}Bg!@D|0hwS*lHoQ4ITOKk#%lQyYejQb>dxB}HoJ(&?wv=SwOSt;`_ z2O`M>mHdxJDNQV`Gfoi`5L?AnW#z8=Fc8p)px?g4r+mt%{H520S59;QM_X}oE|?8t zA-#^y)XX)z{_Z9MZ04i(5fsewSG1xl)zXOpCV_fWR-qMLsn(#?-M5N_7U2>BMi~aJ zsqDjCp$l3=&g`s=%?}THb>_;sI`1vrH+O%xSZ$xw+{e`r)dXztB~v?A8&_m%+?4F; zQ2CTqLMy$@4(NH~pfzgeT%k2|VQi)( zz#5b;SW{SnSSO=pu3XXTK`Y_9$d#-@E4rxGDp?P3MHxbCrR#-qHJ+-o49pL6r6WeE z$geoNbQu_^5GC~8nJf8>sGyQ+ZiG@b`|{)iRkM!{C|NRMwsV zyvDyD=yQ-o_I`WX6~-%FGZq0BTCUmkLo2$VWoaW>(Io>!d(h%Dp(R()5+hlR#Bdc_ zS~$JR#zRY8jFOS8^lIe_T0)_#xb4ir^C%oedSGW2D-uWO=+!k`5v!X~eJfT6t{Q@R zC#BLygjxpVK{Ns5idf|z603~*%GHQfM5%%{R~OY05tTV#iJ};aOQVLRA?kofK>Za@ zivxFakU`Y(L(54MuINIz3lp#pE!UjUiZ08sw2apHc|Aq62d#u_b@HJllNaw0LG=Jv z(8?Z@tO8eb<9TrvOS!V3!snT*lxm0i=0BbgS1zwGwKYYmYimVX22ohjL~s)8t>5a^ zfh1`{Z#Mp<6iYI!g@sftKlM|?GYGMVy0ebC;D)1B2$(e)EmL4jSiU6i0J0%8 zn&hNf8c=9Pn8{?0qK1{^Q7!q;hbYJ44v`2b9A!|)BKexx6kw?q9#Bz$B==5{CJw^o z=Uzjgir#pD%JD&ks9UaYZUc7%c=Jh3cD=zDQ7cqdDvUotplJAE@MY2EO-P_jO6mA0 z88$3*cPyzw6;YZLY3!5oDWX!Y`lI42Meu;nXMDzI{B^hSnVAhhT()L*^@*0+#7eBccPJpC;}xa2dEI0Kq*$k4pHPnDTSH_ zRdr8|kN^yXtOR}bXMgtRe9q^5?t|e4!Yd~n!EvI?VGHM?Ws$riwlU_a8k(?=F_-Q7 z=eE&`Qmqv&8PHr(q02;Q9mXQZC6lr$qKkG(xU`!TBD$#7pkMd>x~p~ZBJH&zU88r>=d{}Lb5om+-`@I> zsfY?HIh4$Z(zcC1lY&gizcv>t0;<6&hog3}q?Br^xJs#piv?Jc6HS z9S5S0SvbYW*E%1YhS8OFQ7zXGEivBS0;!gj3TRpWNY-#ASDRhf>1rmDtjxUJ3aTaH zjY3=%GYYvBWfDX{1sgi+Ks2{ujkJGD$;Elc8Zv$P)nJd?vQf(7`ckB(p zm8*teN+luMP1B7`rBpgJt|%3#SPsoA;fYnVBa5y&K{bXdqDH9{7gx%CTlvpQsfMTn zPJi=*0lF2fxPn%~6=0ziT_ap*hgNhEE?4WaGg{G=-Ab~oR6xtxiMCWESu`A7D_70L z;VRXND>DLG@?V%8T3&&~TR2xU{wNjrU9D@5sAjrOX$YoNO@Ey=IBB;W`*0<1vL}u5 z8BU1Ox$-RM#$QHV6|_0AN~2ao)!;LOBB}`(OUYD9b-?NKKmYT;;0wOsZ+S4hz{`fa zgw1hAyI>}q3tBUF0}SVYN0*2$XlV*z6#%oG?3UiKQbD^Kg;GJa&?O{CuAn87tfpZ% zhND_ijVqHv{spvDL}_LkMwbc_2QdSYbZ|RlM3{!--p6I7S6M8obzgV^SsRHPTh(lB z&N@X(W%f0TZCyz$1;6Xm4z4`awGhj(G(?&BX;kBnI>nN-lpl!#lGF(~OrxY!Vx?D} z#i-Nh5|&hI_#sLm6gJgb(N!M_@$x(N_@XcRqA&j9FMiXT-t?tQeA$?BUNLg*UOv}BEP0?!2pTf7;OdIV!5UwX&FHB??pLNpo$OS>A2 zIeBTEn?yZ}F$vFTH7OM0fL3;;Cl9uqOpGaOXrW6)7mKxyLcoZJ(Ru_|O=OS{S3#v0 zG(|*#O0!sw#tABm6~> zB19!bU-*Sz2&Y2nkuV?)JAeBgf5#HP^A!HEm)Z8lA9 z972WnKo$~9`h%ydDT7`U0Ao8_ZHUpq`IdwNI(T-{(&XF@+-gc ztG?>1{=uh(*LdZ`SA4}+IEF(FjE?Lq=*o#<49u>9cCEt^{LtDI_H#EIFVHn;q03CP zWXp$^=Hdi$1(KunsJZ}HbjhKVQZ2a^=n5^#7Y3qG4ru9mMrDLc?G$lUE%l{W6Ipli z((?g>OqgzO*dtv!Z~IraY2luld@q{o1d)jj#Xuum6Wn@sFIsOT2QzyB);Q{-Hgh(zzlHV>34g zuyhP&E?X~Hf=IritFgG-u1`NZE{ru0v+*$|le|Pv9so9INj~A)jqQgj3bYgmT?5!~ z6y(6I{b4t zA7zdZsOFtA(I}y6gksdG8HX!SAu6aKfP|om5VQPBviE71i*%`ap_v$6gx9((a2%IDBGCro*sUHxtTU0$>&h#+GCqtFXhj$8y2usD z646Dt9?cb~a_pPNz328zrgZN)>eZPmu3*H9o@+YtK4L}rB~UVTE2899a8rpDqJl~x z)FlU{Oq5EPIK*n^9l20eqbj24$pNYeiI&J&Q2Jf}*b?(|FB=GxuT(3*Fy<^U4y~Dz zGZx2v=>=kIAVwF-vMy@8nt2PCgacY7(hN+f;sEehYflsoimho}siYpGSnTGW0 zC3EGB4MCbIT**2Id%U0#Ts+C$Ci(||Fa@?WLolVH&z39$3>B{O>Tv}s<4+JPP;pi~ z)tM`kf=r2QmAc?cfe=Lm1g=0urbelZBqbiAsEX1f0TP1;RA3WC|M+cu!#8|`UE2wN z^_uW&>j;C^&;?x>hgNhEOcEMege%q33&eKNG7YWE0>{Z4h*Vk<_<^}elpKa(MN3!8 zAkqy;8x)ag`7?=Gva;pr4=hiu!e@X-f<-eC8@=mAP_}rnYMis@*Vd zp93;ioYm$gcc@H%Vl}o(PIByQRpT$Hh?Qi@s-RTNh9v7{nb+4!V0LJ8qa=+Y0z%2u zP7$$`C0AA@R%k^RGxbn`kXwSbKfm!Czww*C>6`wEJ^snt=&!bZF#BF6yk0=gdoek% zAZw4B5WPQrQ#bxI`_h+;lvh7k=Xo(fU2 zr%B~=?)!{}pn{XZkylp^0tKgop~^}rs2Fup_Y?^RV1NWR0w##Q`J2D_Tfg;N|LF(A z3%=!BzQrqxe`*g0*+F|kniCy#3}y&NyMTR+p=<1x?f{r|Ss*FaKEhZu`n8ouE78?V z>hm+_AdD6_J62*x|Z)oOR%8 zWz0W`JQb*-(c2w|Ow9u;7LHgUx$)=hpmG_56Qby6e>mHzJ<-3~dZpJF-i^e8Ez+DN9V3ZO4QZGi6bxpr8Cse` zBwyB*a9L?Li5A}Np=^+DfXR&R(}w7x@Bl-X#$+c%bP+D84lVhQE)~)5(4tx*wB~_B zbg8KltF?$Or6(_7*r+e5Q8J(%c*!Ba*HP>gW>9N7uX#M`&4Bsx@YwWOauq z8$EfD84ain1-hU`xa3eub*m{Ly=;b5>t!9i8<6c+T$RHRNwS736(kNr7uBK|29wy~ zy7?dIfflI|(M5u25k*=xYTe)E>VjUKxpJb!%6SE_UBj6xmyM{PB33yo3nWuP#RgbA zvC?9)L8-KxrW>xh0hB#`8dP#?DBy}%>F9yV1jJPuHBc$p0V>j=z9dB;N~k`yfy6(* zN00>6cYW7){fqa6e=2$r?;l_8k9vcM55rkz|9 zD-$rW>P~QMRYQ>G4_7@>aJwYohG0+)SGs6L@GBbIm;QXTo%)WWY0j-VYY5KxGXaT}TZxgWoRuM{BO=NK1eM`#2=Y{L z>e+(n4=O~36B*ZW`i>)|@RCOA5yeyxD;fnS6G7)P9+b+kF#CEorPGbST>9#%P(&!m zMT1Y3fu!_95gy?2-QWG)-}61+^RMjjz2E!2-~avJ|F7=xyO;RaPT?h9IpK{C;5fk; znNAd7$(IX2b+?V29@KjX=9+0Nx~xKX0L;=d@Mb;0XqSaE0O*npfH9mhlY3`G15Ea~ zEPX1mZmxySmF?WSrd9$TUODu;X`)8mt*e)DgDb&h&As6~BL$f1GuUUYvRL4mIQT0+ z_nPh>SFRi_qS8a>%2OdKsF=NGADI#^l2~!?6DAk}sl>D20?)%gNRH|ddxb0Fbp=z`uT{4oIcM7fI zN{=Ohgzx*l@59DI(C_|%ANYYE{J|gmJ$wA#Q~b~m{ZK#i?_MVU^*wOsAPxnv7;|vv zI_Ma{R@0T^qF~h35`+nkuF$efbkQ!#Z0$NLw0iOYEe!~*o;-w>Od5r{Rc--hCQ7wl zHYVghv~Z>6p`}L966&Rb&=MnDiW^syq-oeFgqCS2$PP{bLynL$agnQtYI=HaVii%T zBC#5oLR3!}hATc0SGqtuxPC+lVudS9(>ntd4`BKFE1Bxqg5-b-QJOKRdjLrvXDSURKw2XA}L}QrwuBy1Buv(6WD-9{Jz`x;XQujHvFxB z8Ngx;kkHztZj&+xcOqyxDY^p8Wss~)7a^sn(CQ}f>%ML?^8lk=mS%xHIE}6(E3`CP z!leh@*Mt_;(v`TP|AQ9E!c~$rXeo!5hn5;`ckCa&{np`gRGwUQw0_H zwSabrD63!>8-m0tr2>^!vi!sc|ipxVXh_ryuefajK@?azPXZv5zv{-__`a`*e<&_Uu8 zU;?hr1uZ9yu51|bY#@@;&@vNOGf%aWEXy z7rBZkP_0AI_zNnnWci7en;K9_3$7Y}pfUlaPH*ChOa+yR&=AzoWGbi>LS34DK}83Y zEKeR(YDzca3Q_a~ROAH!co>aBNJJrLjeqlQpv=GSGPZ3-zEZrQ%UKAcfxDu$daY(6 zu2wTovMf#GbbA)Z%J#%&7YHZa!W`ChvY0`m;Sm|FzJ+8PB5m(*uQL5~^ zk`b#>Do_y(>M=yo6Hp-`s78DU5oSi80_ykg@o(+XerRo4_9H(MT9|Ywln!0am1M1G zp?%OwvRpH<9kfitM&UepfR$u+MubGv%2E{lJ4^iAdqB)T zjf}y}5khO|%E^;Q=Y_N&T;?*gqRT*Zoi5k}r?=5%rt6e$3_}Z7gqj(EmM#k|qmZ^6 zg*}01w4g=yS&Ko7d*?S+u1v#j3A0$CrCursEiS83=*G}6GMkJ-(I_;z=*(dbj&*0E z3WjP8e*URkIsTaT#L5Mj$a!@{aaQcKu>?)~JIlmSbnGm`r&hK-2(^CRtZ>K z6(L#NFPAlRsUT$-y3|x<)f!sSrS!%YwA>YoNB4(+6~kQ|qAW6_6kxbT?>Zk{!#Wv5%Qb5XgFCudM8XwUG&!y;TysIo zKnyLJkt;5gyrV0$w5L%xXc>rF_{Ca=uWmWHP0aTXSKaR!Kgk0u^VaB0Z#MJnp%FilW#O93JqyVSEn^W^BrCM2mYJwS`HDfyK*SZx!G5@7O0pV-Nmgjl z0kh`ia0RM)c!jHO2IFdO10Udu%+3(B5VyM4)dO}DkXUIY8K75MEU_{K>6Ia90un1j zP)o|5OyVl2JTQ!_ZUBRdvr-gXtwvqF4p4E_ai!dizr+d*kRVe9P5?C={il2M*LB}d zyevsOqZM7w(rx347OnuF<6^f+mQhG-J=Y2?Tv?X|n)T2kS@ii=Cs$}U0R?jfe(FkQ zb5@}0F}s#wt_CWtge%TUihCe|Aqq*O@Wzb*Mxy;li!ckw>cK)aYXA z$ILenU8ieaA8K(~6xftE3PX!(dF-IM8ih%g%;-Uq#gURMqfl4sP?mKhi_6l&+L^N* z$x;z5-zZe3jMnHCmz9Ah8U|CNki~jlbMQXBa-w;>z}*Qq5ofN*>>JT8MdEfr>AUE2d(g@^~S0)eYc0t6sWrUW0Je+OR1EVdYFC6 zji_uD3_t~ml!pWX=0D%#zj!dbWaTdTavVn!0p=7LcxX9wGtpH6o|ZNcO+#GGlLrlA zrc+=GoX@7wMWrcrqfnz|;N{9KbJLK^l06;j=6cYItE~H=rOh9~mAgVSiz&*w=d$=E zk4B&Bue`u35hV;k=E^}Df^ZcMj^UgYqBtu7Z;qW(38vjGhN*oGS2B=TQL3Pl9AX73 z6ELVGP%>q;r|X8oh!v=MRHYDZ+YuE`ZUb}dJw`D55T&MytIGNFR0RM?fW%73PyN(S z{q#@&^nbO-&)i0Twe^G9_cHNc?twuEaj2P$j!d@+VUFZTi+No%Op^Ic0h5CZz zS_rg8vP{G1vV6^zWcA68%rFcjE3}dqxi{DHp+&VaT4%jdUjoAO zjA{Yk%oRf(TAO{}V?HRflWF&Y16PiN(ue{TJ#?bHI+;RLPp+DP-3i8(hYYS?a8~YZ zGgpRSO4Va_%ct8Wpz){IC^;8Org$nM@2*E<%Ar1`QHbhMl~kL6GS7`D0i`lTw0w`J zlqp-KYDSMb!bw3@wyBpiWyzB!T!cyx{oK#}+|U2~&;Po0sxT-tyGKn04B7+ zQ#?nmQYy|Ws7&p+3MxY|b7crxCa64M(Mpz|R}U&;B{P&NsND5P9Y>*0ALhysQIxnE zuTBuss4-NyA|NyGk|`L()vYr93{+rqm!k`R^BU|G-V#^jYembsnu*RU&;_mGiq|4s zxN^-Ti`a%1;nFO)G7T9mXqkz)B3bK)J38)Fu3iaOnv_^ctO?j-D+%`$al}f4t4L2l z`_xadl#EynRNeX+e<>BH604>jsDM#G1xEkv)52>~tpE$H#-d{i#5$MTfh23Va#heW znyHpajsK@|MY3phT=nntf!tW~n;0A*li zlB^z(nn!QFdeuFkY!E9Bfdyr&Oh97AKWIsUe+^gWNS?~w7N`_U$xOiYc>=jmVzmw` zcF4d2K&~mMOti!bR{z~Su@aY%g_a{Y)Hp6jcA|&5%4-c*R$&yTS4^V^4kKB5>TQgx z%oS%PJbE>7&;Dwhl_w1DTUkL58D3g)2i4RGgJ|V-lFFxXN5< zOuize@~DuB)w~k!=`>qq0un2B*AU^X)&~ow46#~o{V0Yilc|WB35W-3(?mlEZ2tQ_ z{)Z+0$5VL8aOW-F=pe8hV-GMVf-#rnymOQ2ssK;5jA^O`Esa2I&2iHZS}c}zS)ftq z-XyeSzyp>n7RlnWbetYE3O(o}S?&#Wr4D6TN3ytgdL`|ij*et02jA;ygBo$~9E*CX zAd5AU&2xm#bQD56wg)d!Ce{%S_iPro3eiS~9>1gcg?-T5=UyO+#qOB+Ke) zLv(rUoOO4{G-#=amTwe>mU>;o6=4BG);;%r(YLz?obU;bdqjTz8m@Y_(48Qt+(ewY zGQJ0@)m%lCxv!Nhf1sjNpmJ*iDoQm_8G`g*R)ea?R%V2bhLhG-1wBrz@>GbL2MeG= z6i)>z1yxoh4yR@x07js~2`ZQY(J%edFa0m~gnuexZ5RtJ2NbEFvp{QZ4~<21xhiP& z@PTkqEsbCl4qBFDY1Ft+453AzH5ADTEeX+UG9y>y9a@YQ)sj8!sZ|Fpcij5dj9{?_ zEp2|_ie%x6#Tv;{RyX@JM086?uP$;0m~IK(6&3@Por_%c@Cu?1xPAKg{@ZU!IMG3@ zm_1x2Rt-VdNoG?jP#J9G_}`ZJ155N{ zFNwPta|BF=mSg6-aGTvi7oBu=VB>rqI}k2tkyf_Q5_AW;ET>Uunb1nLEZ;o~_bwY$ zE3YM2BrCL%ESdDEL1IITftPJu8HIzEiWnu0LhVno)XRz>9jNWjwQL0un0^ue8;(a>ZPk3lg4Q85!x7qV#nA zS-E1U=uAqL@}T88a+Qr|=R%9!GL!+IWEqI=SRdx9X-KQ%$|IN2D?R8QCzthd^eXGl zVhI+@Co->GuU-yUoRtYktT=W<&>fIW&K!JzD`I5`CRT=^dYL#TAhBu)nn8+d{E-p& zZo;%8F9)s+I9weB>VLl*gv$#WmkmTr8ii-QdNfxW$J5ay3t9}oHC$1C_tz{|qtKlZ zANw5V;K~)W+}Xtyi#5ShO)%}kKXoUFLvI0OAL8V%9^k6S3+@Dkn+tcZZa4VD%$1u# zH@R*GnRd%$u85V<&k1u0km~2dgDw( zpaz%|VHn9xL#pK(TouW}Jk{dijY3^ui1UY5!Dz8qM3{AVZ(^menU9_EU#1UoufhuPeR5SYk6IcJ|5`S=s|7#Eb2tBV9G3E#k6@}Vx_@VB(6Y3sp5)KnSCo) zO03ocRTGfZK*C%TBUZ49pSBBDe{g;tTG0h9Z=abMT~2fjS6M7*8RZs2vM8_xK9wuE zB3aNH$)fzS`c}$SUt_?ta6{@L?ZbNIA%lk}K5+|W7-Wt`Jb=ExCb-=gNh$EV%z`*mFZ&!8AiBTp&}^&07FE93LZE)v-E$T!fQs) zyd|zivf_#)8ikD9NEXdRJIj}3H40s`rdYYMD34G)@(nH1kX|tZGYWI>XRdUpM>m6( zr=zkh?UMgW^onG8+TgA&z2c5`=f3$X1MXn49<5iea)q*$D}b4Xu#BsjhPX0zSIK%S z<%-2R&%rBw`}K41Rjyv;>VfABZ`*ps5}Sh@yCLZD0--Pmjig7+!Dit9vxJ{;Tr&q> zf?n~K=Ah>-T!E*feW1fL9Q@S_nu8bh>bd*&w*{ow6)8MZ&)s{Pel6jy|+M-AuuL66JUM-7jjgKu8F@{r;Dy#3AYukL%^POr|- zMX!8*^=9X4_3aNlzj|K&>aB>Y`4Gnr?YjPRoM-jz_i=Uje6Y`PJnMUL&qXi#_VaVm zYkd1l=IZ+AqAy|&z6ibYh;{ua$F0G$em?k2&)d(R;~YL8oX>F%&)fUZdHo#c;`8?P za~!vXZrsjXWyqt;w!6Q%8O*d_$<;apeMETixu|Qt=JUbx^Y-)SgFeSOb9H{+{#-tH zZVvkFkEinRbK*+9n(vD~`uhy&)%kNAde!er^nHeB`rP?(pATOA+!RkFI<|dj8yb{XTdUfUZ zuijep>H)6ilfh^Gp3JXiz3N+7EZq6`Cgyv{&-%T-e#6UG8VLCMy}tE(G6#Qk{{EGx z?k31J-;=qhS72xqHVykqgBh30YP(LrxblLODzTamol~me%AJCf_T?*r=@TViX6VaT zzS`$Y7ruIN%^dU%v_8b~3C_ju^}Q9%!TEihtb6VqSHA1jE#Z8>{hHs$@qNYf_xe_@ ze740QoWC#X<1pXu?yG%nxBDfp^Y{8#-#*GwCf__!FW*I(Zy@`^j1LMuK4PRr-|qA5 zeXKjE3WPvqpKse{Ow^FpPl5`B!dn`G;pCWoWz>n{%6UQcOy3vvC7JoMs9P0Zmz^)k z#FcMo^H;uk)tCBwbxrpA9`gGAD__v{YX$Qq8DCiH_i@(WAM{ns^~<8Z_;laz<2)CC z_1w9-=JzJ#$|J1x`|UcEW$l-|*jHce^ZiL__Xx{Z`}!)fZ}9THBnw);HR_94ZnDS% zae$VO$~5SzJ5 ztb&SIxdvC&myr9is1|U|^Ce_o7VXPdzIoL*kU>SFaW!8So!^_dk}Kaso-ZN$;;!$9 z^X<=tD-YYd8T629;^Kc##&@*5Soq@TaFtR$Fb5BMZ5;eLIof3d#Px71Xum)1mFJf9Hg19ipBCB>ApCMD_?Qf6oZyW4fB=Jhq>}? zZKKdrEULw2^?RvC0Lk(IM|wRW)WXv4QNu`b_@Z|#5F47~l1em-1zz3@h2KlDDWgReh=aM4(c-dHR-w6Q<4KrP061`E6edK`b!KdS-pf|5h*d-}Z^9|^ z>Xgc|{VZ1B^rKq4$vXabKZYecD^8&5_1?&*9k_Cq zyn0X(D>o5nPptgXkXu)G8P{-S`RHD>s9FwM4EGD>sA8mF)Ta!p-3P_ZiZw zXXT2qaim{(BJ1w$4wc2qWkJ_RgdR1lqY&*g3j0-hznbb- z2nQ|qw*6|VdlPqs9ypl$e!Iy@e8UXi?BkCSR~S+XaST9vzqE~+KZW`x^t!vbB&X~g1m8np$l57tkwi1z(T8s52(P{3K&`nvvQ)J>^ADgM}Ih zdCkPd=L|2DD+{E_gO;^>)IhR)5lcdR5Kpy+t8NTsPbTTVr&ysCS9;l}v7x2AO+)?e zyY6ZfT13EzAq%0!Boi)`<#1NC2v;*Pov{tAut~mv)L&Pk`~-oB3aXSUoE%dSE9W9p z169t-RRtBL0+kk^v~gt>!xdXKP`L}%Sv^|-Rbs_|CRU&_0ZF~=$)s)#Dq=M^gHPp( zGO$&|inAhCh9KQI>(!f)t3K07uST-W!TGk#!(7RgQJ7>k3T4s=fL5y2D3o@SBD6@B ziWnj!ON~NHy-XS6u%e~11Vls^)lz-J5?a(okew!D%(P9!)@?X>r3fkq!Bs?M)SW1( zoLA(mK!qquCBRQz$?S*~$Jh|Gz?2G9T1i_q1VKft$T%@4RzXFq3_)BG|KZ9*!oDGs zUJ)yiUiG{4t6rVCGLlwv<>{q?^&Gi!s77Ja(5QWQ4!#Jki~wlKEws3-ES6C?Xemcr zsZnUDmkJVx&@v54mdct+Jtt#?B-sK1mg{Ytcty9eSb81k*+f^aT1T?8Z zr3yZfRG+Y5On?Cu@DP+|f)E|T3wDBTHs0tU4&{I%oC1l#b6#vW0bLd5 z;RJp}=>=XLOP0VcQmUL4jj~L0pHf*eqTocm-Ogw?{!?c1REW}#ZhW*S{fCppa#o<~ z$(6Lj$;eOwpRDQkoE4(n396J4GhAibd&odTlv}J%L|3lNHC&0g8MO0guAB~9Oda78 zgzF+#M&Y1ExRNY4CWDr>lPo?{HmFwjhH|9`L(5F0T{20sBsR3nMA?>h?QBv+mvV6L zp`}dd;)In?5g8bCLCfe-*|G78jxJ~=UxuT=20}#lj6=>2+RdgPdV!Zkqjz~PsG549 ziYp9rcM(N7v+EH>RD;T;QmTley**yAG~?bfSxQjx0G3aqc&ecK(l6cq3)>zn1Qn%X zBs8Wb9jHu%#LA=?s61rQ=3}cs<++e&j|Z-3g~~=0sE8HQPFsSCQVFs%4;dcTEC1@1 z6KM4IvtFIKa&zj!1j%X|y5Iv>I)!OuAO|fCg)6!(8=@=JU^kp2EB1_nZycITFLU?#<+s0sVW+U=zVEi8HFS(u1HpB z#g%rJ{E;kejw^TQBrCMkE0?uC(Tb}<3s*A@p;h3dfry-m9kC}HKlhqV;PybHz~>N^ zOTWlf;}29OU=KpC;mYz2L6*P-Bvyu?%+M=A!cAgGutK32AkiJX-Z zc*uY&rQxgwDwg=nmEtx58-lB8-^bv+bMP)!@9}7^Sa)2xu+Yl7>w@8m%QDlgD6XK@ zDAZ8Q0JLNyw74t{C|x=+qeZgxrV%h`aal%#w7W|hv{-j@B(#(%;UWl%Xy}Y^nT8}w zt<5H(?j(f^0)rqj0v?n{3^sOdglSPHKkQ}E=v|KBP!1>%>)=k|bcY+jWQv>`)}Yb_ z+99Z{BCagW5Nra1N-J4Dp9v~N@dnyWX0q#`B37W{B{V6nBoZV9=peHi{m^s;jY$)cYJv`8zZb^U^B=@Hi5>Y$~4C^Nb&ToOV{ zLNZz;UAov&Xi+T&UK*uTw{op!fzEYf$j!2~=;A}nL_Mx3s)H_GCBPJ}dqbr(cK}AX zx;-Qv1VqI#M!1@cV1NXjp*DkAupPGkHAV8`!W$jLp>|+5LnWMrNHTb4u~X-)5XAu^ zim2irRIb^Lts4-lFxe9;P{GMc^$`PL`9Vdd5JkyZ&}7Q^3o5;-Nh8Vx>@j;oaG=7K zHt!x#jVKjAObS%6$DyDyfDA!grBoa{u`;SK(BlPE2=<#5cLQk5d6+P9QLpy9#+!`? z4&F}mj6&hC!YN>UK&z*tLzjW*f+;Pu1hlNBQAm)rPjq?UAPGd9B|w)OWOT`rbfJsF zN0%IuELmkO3<7i+h!WnzQh=Ek*)4UMCl44ST+Kv9%*g|6os24OFa;Q4DS$D9avPR= zU}lYe7(%vDgi_E7#}tSPq^wkf4^*xSOFdOUlz%VMWXIF&0fjvBR}JlMgLO2y_Kl`ZIDAMZ;Ks^{=-Iw?XBNj*v__ zrZD@Qh(eB1WvFmvO!r`cSmDYwr&OS_5b|qX7MN0j%JjGVm&O&bG6YAjOhA!dHU1vf zs|Blfe;ijc4M(qxLI$3$>IGsOTF=Cl9&~FHT8%r^uO-!Hgh?@IDTmS|S)s)M z=duPZ)6f{=~P)qE~pGPb|S6q{M>8A4&###`y5c@rkrT*`#=S3 zp2}4jf0Rnh4IsS@Dnrm@w=N6RK0#&lTYf{(1k`JWpr$hf6RU)Eoez2r>a{S41k#kNtVp_q}0ez3w42(fil9S zaC!I3}> zk}TFj!vYLi@+{$cS@I1FK172nis}$9fN6il;#<^?Ca7bK0ZfU}C8!4tQTpx{BLNjg zBtpcHcG&4(+hVftE=Ne69J9v=&J|0}OQr;+iX}MFRS(~EfoonLDQFh!vOvq!L?$4y zvV8p&PHt+t6HKNMMX4AGy(yCs#aZ>(DzTD$L-pg#msY!=eI0*vf6#1xCqhe`{I;dPT$rXrd z`~?-9G!d01R+g{75XB)-avi7d(kMic`kq-yV?@cV`)*<-;gm}9xe=kk6(z48QHrHx z-2<{!L6un1C}Btm08p66aYeO~vgpddL(2ih4%f}cg-KSbWg5CFz;CyyJ6%mf7E45z z9!avGMYW=ffwz2lfEM9G7qp1Ebh%}YE>bUz`gE87?Rn{nmX0D0lPpssSOa+zn#ub^0C?(L~D$?vD zQ$c0QtV#tcHC5sRSD*qz_jGNq)T>8x<*Gs}x?HDgekQI$OS=tM^O3Y1@)Ei=x~P_c zsEg+gQ5DQYTxt1n@F7aAIg}>JQYJyQ;wrTI7%|Dpbn#v2 zf>x46YKnwwfN5uCtbIRE-`WP1Lq(Ls3S3dhh#EsRG6gDwn^=+A^^rnc5i9LurJ&ME zI?DuX{81`UNlsif0pm)0k|_Zy>18>jdbk3W!J#5?1*+j{CLm{Zjb6QSu9!3eD4K>w z?U^fA6K+k+Mvr|Kjtw2VS73s*+KNS0A3+tRM12Q9NhX-pH6rA$J- z2m-VOiHI(8q0qPrEp=}i5*bK{(XJVbVROLD4-=?SIZS#xs3OW?g|j$aL^*ZN%2hS~ zC~9132Yulol~{-1K&6!|e{9uoC07HLA*d^LD58SO&C!^vlnPWDTwPv1R~h?M%k(rx zhpUaPU%&ki6vovmSs>^41i%I@qmVPS1ffSpvb2xe6T+pN^pqr^i*Nx*0f-EaHk}adazPE(uz~Rfr@DSC%P4%i1LYTB%mTrS9?eyw&@lzo zatauaWTjeYCt0ah)6fOSRcOUklEpo4Z0)~TL96F+mYh&6ttVYN5n3cm_GD5@LknG0 zYb2{XL}=x>#>@kZb}1Z95K0+frjIIbbMdR5Jn2flz#vjEbOqRm*t*ldwvEOF%6kda zriQzN!mYD}6Txiof!tNmD2j@F{CDe@mCB-9j@j4UpOx+w;4>_oOs!B!j$B0)3t<9k zOidb5luDQjvQ4Z~DvuXLVii$L3#ho47sOTCHFFS$Bo32A52AzC^X1CIldKgjxzd9x zTG}(NLJLZBv+fT| z;neGcs;TFgrk*%M1@9Fq@M{6>5K)wBCZGid)&5Z7)2+SPN5J(OsOb4qxiS~b2wX*! z?iRR8tOhDlFkBI<^on$Jr`A^K8-giSPU)$7^%A(!G8RaatyB|t0aS-F=$%SF0+#M=7BAi3U9$=GBr>U zs|KGb?7WB)@J^;E6{x`PI<-SYfr?lWVe4ACVy>(`u7WDA%sxsbI4e?5@O5Y(*_eRB zP-qAqxSH`dj~C8dnMyp>glR=#^6JoffU9@C8_?pi5Ll#FhUrLFs)b%-cSfNpY!tdG zqp)e1d)EtwxYiIxA?t2wtfNsFTIizEM4M!phK!b+@bFS3T|<|FD2GyN3J8Gd+(x0y z8y1|cP!260TFMk%3YXE!#sf@Q^IC*U7*7CeCISo+Vi?=>Ymcz8o#^L-;tuA`FJw7d z#5%H5M3nP3kzGTx4^fmVukNxVimeh2L7EIFVX<1t!VN(!7E#(wW)NlkiJ}1uYF_`SKteJ$%T+OO$lQn6W6CLaR!w^hQ@ViQOj}888D_ z3YLh4S@SW{lrqwY#=w@EDZL;mNWk8T-_GEZP5;`~i;J{q3^}P3&Xp)RuOLl8%1RL^ zp&bIr#pln%${ISyhTtd_{b8KWT)oTPfZ0K>;;MPtT>!LFEoTg^=yE+S zOrR^YT(FCWR&;3)E7B~X6)GhAwDHBM&d+7G2Pi?a<<8g(@@|R|SI> z5g=khDPs&>>PstxiVJ|nz&0=U7@xn*t=qW8=gFTSOoG}*ltaN)IIM7%!6|8)k%uT@ zPoJRLdsUGE{kNna=kipW#KxDZYNoCA~SM@tI+CssWi?VqV&cU$ucQK zXeo!%K+7~yCIKzAQ$&HT&{A22hE{Z?T7yfGom#A+Kat0mNqHe1G=EXQaCxaKzJJE+E~G$ zBC}?nB?x0(vsjk}S|*}Qe_{D_JEE9RP)W{=KkigZX4Fjq4J)LVm2C({6sQzJMFuLS zMQ|@Fh$z8Xfl8?CbL1*zvmMpChAY<-TG8b?sVnO)qKo!sv2Z2gswWRk!`vpxBI(c) z2^X&=jZzv~(yMdjIRme$374Q+ilW~&z6dZ?TWvhLXcxs0l^bCB`CY(nHX~v?We;tl zv29kWsppsiw@wsG&I@ee8eG*jr$1}^bS7Knf+NZ*gf_7*L^bzGv=Fff{IcJx?uv65y4j{R*%-JYq)YcBp1#OY}XT7(M7m) zfr}T>rAMsD>YDQ1n^?8A%Yam%EA7&E64kw-evB@%uT_PaD8p0>S~9Pr0hV?thfd#( z{LR-*Rc#%MVWzTTFY?W=RAUTa#inAn5gu&;bBOg{?R$Hy?y|J$l5iI4B&d@}pkfL6 z0#TI8HSf~9-Tev6u{11MrqD`y%G!e}qCh1xa)l*9>Ji0M$Rv%DSi!`uP|3g0;3}f) zlc`1wH8^mkrYajzL4_*{liCa<4Z(v^f2UJ43LBT+a#k%zc6_IURuNshaNc|Yeza>- z*xz*XHF$s#u2f6c08F4O13yn5q(ySZZuJNPUD7C|l=w@pB%@2h_rz}x=M^HrM!{67 zTSZc!c1hW4!17=TTGbD^l{z|eUqohGZ#lq|D52UJMF^qDWl$vi3yt6+2PB;$XjDX5 zVE)`Iqkt)-<$IO(gWxfh%JX zSJFkYQY})iF=@VtE}bjSaTQu|r8KFQG6~Z}1vkI4N7_ZWDs(aeFp>fTJWQ;NMcRGa zUfH%8=TKNJ5-X=mrkq;9JEBr5P`OUiJfbKS?X{c+Uqo4~RVnEjh3Sv0gIF;Mt5SiA;7j9~D-$rK>M7`m)x%toj+7*&A}q{R&Z;43 z`-nMspI*_%k*rjUWZ@j`yJ+1AmllXCTWDE}MUgCPM3;f6k4%4PrCK9gW8eoc3Ecd| z$KHG~UWQ4QY#S3o34~fG3c57Dz?e`tv035$IuwmlW{{LegT)K$J--6>_U> zn~8ER^IJdfj4>pQ#R{ZSO16pD9?GboFiXTn#}s`f4R3f5yQ)3I##k$Z`#T#cMNr9nZbTJ?x`b2ng${^_f|H7c@9<1qjc^TME@n_qyIiV^w*;}nwb`w$TXwnv%&HrR=#mfttsK{kMRd`w zW@3Imy3(#~I)3an9~+LUquCig7f~`6RI(?NvZ`l= z{?)}&E$6t}nY!UBm%anFd37aAqYx#6if){_Leq>hJEq&sj0 zfBjec-sSC%wsIR(;p75}k<*~k0c+tDkK?+W_l8_Q>|tZ2}Ru8UmdvZAY*D3ckj=z^A1 z=eXp*(Bp9ht>_{GDmZAVY4ufW5nZ+b3$2TQp`|!b)L(D^ar<+iirBVJ>ih0*nac zwHi8=HOb0x9q2kJ7|fEdwktyIum8G2H9jh+;;OUTx)_6RAJp3hRIbwn4^hUt<&0Qa zsnALm&JP^8f>RMx1YZsx=87j#l=MoC3iD;gpCNc9SL+a5$@w*>K-c;L6VrReDt$>7 zVH6`=O=R1IE3f66o8Yz9RQ;n^XZE5Fn67H(h!lL zjI#;}+c8vjR%}+R#%p=O`uYP@0K3RlgxdyKbanAiG#b zo;;jTbThn{=TUWsRR}F(MOdnj>M6^IlT@q%6-)ZD2r5}EbS|hODvcVMswjE&Cg9*S zS}{beT&+08QnWlPSKc*zwsVoIjFxSHC0u8&tj;n8w4$pFKr6cR+BkV_IB3mSoXIHd z+i2XQ;h2IcP+f03<=Z4|5wU7*J5FqyNwMKl zOa1orK)6oVY`9NYj%9%=6Qz|zMA2})Cib@5Zv6zD#2Bi9YPbrgW``l7E-6(+H31J? zB~~sD^$%F+mWdXy3N1WzkY?v{za~$ zYv!Gubq>BluI8!&4E(y_0j{De$tn-Sl@yh(0E3oHu3Uvyz1)n@+G?RF-7pSd!xg$# zw3>{Hj;lje(VHcKN%q7YH)4Gi9pq>(U znUSgSRMJ>JALc5hf>ZOwb}IPNxB}#=eq*ule4|!xcw*om=1Sv`tO=@R`PXnIrTGeN zDg6Vd?MPOmB(BDBjp0gQ~Od)l?? z3_@05+Mm%jJL_BQuPm)NMfE!Su(WZ%M^}re)un5hfvP^Tm4R?VR8UFIjKA*w3_*G| zO4Sg=6$iqHOeo3=qGvzzEj?Er6x5023BsIp~_z4Q6JdwvvRR zfoLmBLdK9LhZC|Y!L0#EeSmSj@%P9RF2<$U!dYN0eKz*LPm6sjpI z@#?GFUrB(+xTzCLcYbgsS0r%_*Km=m(Jrfi)|soEyoL&`=vuWax^N|>6EZw#p{u}{ zqO54)O4X{MQWnk1RAMkw`iDsyRMs8X9AZ6)eTNOC*S^XYewyD8^E>)fgurpT&VD9_t0i;+;pa!bJDX?)qIIS|Za%E8| z)y-Y;{)gquLqv_FKb5OdD#@R~RV{COyRFp#(f3YE(zNvz|>T6D|B0c4O+v)0kbna z{bYT86eWNiu&uK=W12aTr%?x}T>nH|p~*5QEdR{at#`QdtA8U_b`D&rf>4gCGf>%S z{LS_}2VXQ-bNp4f&Roqkw}j9-a7Cp{!uSDb9k>du?8FY&&6iFk{B}xgf2xJLtd0v~ zBV3g-z|xJ`D*edU?5u3uw?8j_U?->|Y9ODh3Vzq=vPXDVsAlxrv36pWQe~?ee`cQ` z`1PhtN~y#aaiyb&sDWw~tBYKjM^kG%$<*xh*Nb}fy1S8vrBUm4)xGsZD_1zbv3>Ul z*D6^Jdcu`t$-~N(9vpcufumYO7vaLyj0s$ga7}?=rf^flQHkn13YM4*W_B);c7`V{ zTHkoyUx}Iv2q)Xr6;v*DuHTO3SQ?hn=elVoU^%gsrNIeQwHqe>k~d z7e6B}qAajJil{(JqgIzbEt&F5rj){|2r6k`2j7ZQYEa3BsGM_Lt*Qcm10Mc*rs#~B zpB!H1jVoH~Syq_G!?zP=bNw?D+i8uqp>>;sn@12~R+f@7fQ^wz$|SjoP|j^@>XkIr zIgqA&>NqvEqr}C4XGisihlh6(oROUla(l?_Pp62S;U|R76oruOL6=6l*I_s6G{bJx zNitV|F2e_?l;A#f8lhM#yH*?t2Rs7i0Mg;F-tttgVr)HE*U%*mUDtD!nV-ohEmv~2 zDp(>GTC>I2VOEZgt!S-ut&FYAT-;w#v_J1{r|m_q(k0jzuG2M7gVZm!E%0HkR-B}6 z9eEKoQ0e07?kl;f%B!lJ)#=T`RT^uXaLu|_y}E`g?YVi=JrXY2zJ@D>o8hu**Qy~0 z#s;$kHiy5$W>`9av>wojg1K$ia1B>h7f~bBM0;c^b56{!l};0CWKuXiq<{uZvg|X z&SN{+wo8Is8`@L4i48@%rFdsEfCT@e{ZTAAQE*BHang)AxE@7J7`Z<B$lHT)_VaJgDJdG?K$w0F2ZhAmg@!M%aj%9U391z>Au91iAX-mpg`5o>eQ z1V|sLY|PLm9nrk$GZONJ80%!p`T?mQcNL-QcGts`!HH4=Dp;c8GJ2r`Cu%cLVN*sp zF&~Mb@p&0Wn7aslBe^#9!f=1qkq_l_KJFo+_m#X1&_r3cz|l(q%)G zv7BpgMOk?hh%itH%22D1NK~cE;0Lpj8tC$VB4Yw(qK60r1CK#S(=xP62@h|aMuyzV;;sP)OWellM3pPT= z5L>QvfQTc;lJ~~!h_vxLk4#sh*h3Q)y;{?eI}rq964CVtREg&`y0@QQ-LQ0*D^fgC zA2vP#bTC;F+P)c!-{lI%;#yq}9_@D8cl%no%9|0c1W@O1w3@EuBF`xNk-<#2fF<3{ zz)D&u8o#hkVJ7bz;OJ%>JvPbC+k0^;Pdae2=!nt?U`n+kY}h*&(e@O@Fp85a{p#c@ djGbJithRmd^sCdaG|#?Yoqe!d;eXf%e*-a@C7u8P diff --git a/java/examples/Books/Nature of Code/chp4_systems/CircleVsBlob/circle.tif b/java/examples/Books/Nature of Code/chp4_systems/CircleVsBlob/circle.tif deleted file mode 100644 index 101ae87753b3f6fc1c7b07684f9bc9cb5ffe9ff5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120768 zcmeI5ze_Aj7RUXuEUR)+5#7*G+(0IA0#Ps#H1K937^snvkrx9u@CW_@6O16385js= zYW@^NML~p(L_uZ1#85F&cR%;}R)*1;>FKWO>F)aac=xtFRj1DRobT=F>8Uz3I$HCu znwpw_)HKw**Zhs6TK@n2NBy6Fop4;6cU<@9@$c9EUHkXH&ezeV_5XeAYiis7I!~+G zj=aAA{HsmvfBvBV?=gS>rymgzfrt>OtE+2kYwPOj>g($p9UYyVoSd1NnVp@To10r$ zSXf+K!%bS~<2L}iD_xEpaZ~yiC zLtiXl2W!~GGWHpziZN>F5D5JE@ndLch-=Qy&d$}Ee;Hh8R+uOIcw#=e- z&>9RODLH)*n3$M&e0+3J1~x*5Bs?9LR&#T+E>kwt1y$I(sV=_0zrDS+K~**(09yz< zB`s!yFz@K~^;H6}N&v!ec4Y2NOH0fC{=QY7GM-NW+AvS{g{!Bh=lc3OKWZI^Kmg{D zPpY)W#>SqXpF_Z?A-)oTJp7XTA1z@IE6Mq2gt_3P{F)kUh&KM9Zv zG7@)nH8eEnF8wp75jh|udFC&Ff&U__6j>uG8q{Y7iiRx<-qj`o*#p0^PySCo`qA8(bUXibe-)r$H zLpSQh(ii3PWG%9v5P2%1M+#9EPif!CT{NF->EUPT#6|yAG8nacc)lQrJ~w$-mO!Mw z=-~@ZefL*3WwB^L9wYMgG!rm1OCc7T@#rMktoo!HCXC(O+<0_Y&Ei6UoK|rvAQN2m z0WdC7snkz0TdfJq%$=^(TeXi70rDIE$3xb7XyHSQMB>9$@*DDs9@eI5iI$H{#jXok z4s#u%7L&$KA-)|Z*WtVyvP|2zlj;~p0wFBSr>ul(Da275L3}3Tw#$j=9WY3O;@j8i zyCD^p;!8%J2P9yrz7`eXRP-!hYGU1;?AxdcNU_0KW0CX037`S9pA9LFs+ym{^AdLp zXuxclTvaEIyCh8cj}lB>vZxbo$}8DP00C2V<5iqL0b(#10(uC3$zsb4gD%NbG6)3U zNJV?oBtr>iqd*lwE?MjzW!4{AOALV^JBw*+w#3N5cpzxQ-zAHU6pcG0gGnObZ>!C{ zy}cwsP%Op?ppZ&0S?npSC4t5hkuZZOq|&{o*{(Wa5EPCL0_ep1C5x&xF6{PhgR^Tk z(TVpOM>8`suJKX4z6qcfkC!Yx3-t}z!HyoEk)~292jM8>AOz4%*-KU?lL<0}`Z`De z&6L&^OY(EMoP%T(au5P&rgSj}O|=Sw*X6#YCuL=`S(o7`cHab0PO-Pby1KfDhX>!5 z)zM`FCKd7icTI1v6j$={y!3m(E0$r`GtpztL3yu>&MFqOLxVUhfiNX&~02Sry ziYYX@xe88I7En?CbgZGFAu$mFBLvXW=Ot@#anXoP84&@r^r@?zogD!Y0V4#^(x^6e3`d0E%KxvK}%RL@HAd zKv7J@5(*J8PN1u+%eYM$6oJ0JK0y!x;{;Uk*f>%dguv9)lsJfhaRMr#W*n&uLSS}w zRvbjYIDuckei^qZgCel7upkH`V4Q$vwi`z(gAma5N;0rPU~X>ChFRHkoPa(LIxYZ9 z;p_R8C9sa0ot&I>oPff&L11)r)P`Bvbew?ZGdL~)OW|w&l_ju_o7H?##|2<1e9dpS z1lDD<%x~9v9G3-PDR$Q5X#Joiwl14JI5;uDf{d0?rtJ! zC@50|P)J!7eQhu}IB3cN*-0b;6!KLzUe27KpC=NCf(lLmZFrH;w{5hWYHF(~XQcu)AF$Bmy8Yrt19}PxEMiN6wfmBL>?EBD+$1Yo2 zTb25w_6ZCc}fGHgEL6UKBWAEvaRUG+(NK6K)v3lm(KJFR6G zw$%k;I9G8xu@7wo@4{LSEf%vUE!b9NHBE3~1h>H2G%azpAuXteyzVc!7>rwBnYL;^ zm{J!cLtFN4TnWYvQdUA2uHe#wVF(2}jA!4rK`Jb%belhQ!Od!YD%+{IZJ&y86dP16 zQ}6166~ru6(zBiJknK|(RTY@MNDE5F3(1C@>+px8PPn!tD5fsR7_6fnesZfmB3ou? zkDh#WLBq&4B2~|96dYjpC~aB?fq=VcMIn_D^nr~O_xAQ&n{PwBMD2SM$q42#nl7=Y zFxyqL6MFu;Ln4ofkw|^)p&ZS`#lkD5XV1*cB=y#dxQH&+Q_y3fq7qJ~QmITPlgs52 zaLFPHVj-du@#>{82{0Rk&)wN<_Tk|nb^^m^JjZ|6=Cp*Vkbq;=)zzibY33cBoSeM9 zy+u}I_=bo0iMRM1Flu!VlR#Tr+xYnS+S=O1#YGe}h7WjxKX`?2VWQAjmI!bUJTx@4 zxVX5pvvYNI6^_gpg|QfsaT#6r;g*sc9kY#%jlI3S)6>%{D=V9un}>&o_xJZf#718% TUB;{9Ovj?r diff --git a/java/examples/Books/Nature of Code/chp4_systems/CircleVsBlob/data/texture.gif b/java/examples/Books/Nature of Code/chp4_systems/CircleVsBlob/data/texture.gif deleted file mode 100644 index 17e84e80677eeefd1f0609e1e2c37d428e6f6f60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1829 zcmV+=2io{YNk%w1VITk?0QUd@000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c z3JVJh3=9kn4Gj(s4i66x5D*X%5fKs+5)%^>6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~EC2ui03ZM$000R8009UbNU)&6g9QTw5I|r+0RspUC}_~&!Gj18Fg|d= zU;%;y1`0G3AV8pi0R##hIG}(*0|*i*RJefQf=vq)Bs^%K;G@U^B>|j#cwoUx2^KPN z@Bku22oN4RXuwb*0>=agewuuUU}6Ld8a#+Fkzz%Qvno)K0MP*h1qckViWHc#r~?TX zIEX;eLWYeTJb3KDQ6t8R5+5>Dcn~+Mzye+GUg$uA#S9%mj4Wx=gh`SiJ#4^05n=-c z#t8}tG?1V{gbN-@w73yOi4-kf!if3OrHYdxJ!Gg5q2Y8-fd?2ssL-K=3minAY$?-b z&K*2;6CPN= zm_W)|;K2zq1OWvYZ~W0nCZe2z3MrjXV#pn5TyaDWEsT)C1Pu_Fo(L}JpoA7}`~gWQ zuH@p&FT2o!N+yTcF@_XD&~QQr6*wT!0~ByzLV{A1kw+t;%rZL63jH;lylBF+9-nyDURSVh7&%(;Nb)UL2v;GE$Fa> z7j!5R3NFof!_GYPz*CMj!?a?_A81e!#0(~EfF}SDU=TtJJ1_yp9gd*#%QWT8qt8C~ zw8M=uvS=a*8&?qjK?4dLP>`ploHii_9*>{`Of}}v!%si?wBwC3v~V&=8?nwntE~V$ zaKU;zECGfcjFiGlG~&F2Pd@ahvyCyZWD>|4RtP~U2NnEi!3QefkOUWT7~%;n$Yf(q zJMN?djx@iZG6^4LL;*w$By1qTkIbDw0})oF(FY}`=(5Z;+<2o+G{eNwNg{NB!2}O2 zh!=rC4NR~B2{8QN#20cLl1VDK43ms9$M_OUD39=wh80EFpuz_ha0!5Gd#Z3l5mlIh z2O^h{(#kBf#F9!Uj{xFE7ftj4g9#i=;3EJEI1pqBFYKTM7H8Zsh$EM5!U-mlAi{?m zU_>!Q4J&B>89|5uB*1_K7=VDn3_d7v#Takg@y8&91i}X$YIG3=5jb>c+JFEUuz=Yb zgrEZANJO!P7-+E3h8kvofkhKT;P8S80Y(tlV+ky<+y)}3AcGD>%0-BXn?q*gY9w5&{wk`mS|-~ki3fCf4M0uq$q1ST*+2}bY%4!FfCJ;@3I z1fmd!93XcUnScc_pn(l=;Dj5h!`a!F` zMMV}-K*5bgL+Yna|_P#Y7676j&XYC2n5TTD(p zzq7?+b!a;C6ZJ-0y-5Q!5(^Xggo(2`KT(Sm{IL~Pe4Wj1;>&U*Ig)IHNFn9Rr8!c$ zL?Mw0_!5ywB@`)zQc<>8r4h+BGBMwMB^Cq%m1j3LXsU}!+yw%cpV;JdwrYgJj*gC; z4rz|f-Y68S)oP(gB9ut7!6Mr+&Fa*5W?LOeE+@TyicAiJ-Q4Ol+pK)#S6^>ybLJ-| zqJsJ^cgtE@`wFr;a)?&u7;G)VPJOFToFfwUd4`O6fQm+EH|d==d#%l8DR8yDs>$ZG zIht&(d|i!VR*Tu7M_n##w;J6Y+1lGP zdBT3vzq;1Y%M}%U6~AQ=wX_It6?_h7aXZANJI-&J(@{IE)g-JoIc#lqgQ>V3aOe+q zcSu%LXv(Y(r`~EXl@%30b#lyRqei4vK~O1WBBey6P>ID_rC6>5iBzf3sYR+nBC-Z% z9T*d!E3z5d5cF=hM&wrd=iGW^y~%B*-3%`yy~V=@)%yS9{uVB7DyG!zfPp%#HyT|d zpNPpC)6{{|-e9$ui5P9w+Z`r^e12jt^q%hlmnW2m=s}I%fa0#efZhxyW1et;w7**3 z+03`-v_a8z`S!?qd;c9xCabSEi^~;Zb$cfcTZ6MhZ#QWhAr1z6;ki5x%;N3Z^|r8> z{|z1B(6`?q{DY2}JAvQpmHeN9zdvdXO?qpi$ygxl4cK16pX)JKKMov8z3&vSk@uHP z5KePL|GHqn`x0qxp0ANq1Fs4QU1Dk|5a$VRlJz$?kI;=pL*CLx3~6|G!X*@=)ScB+ z?VWX;@2s9`@2vefM_bL#0*SjcFR^#7yP#R^rXq8r$pLxf3V}qfgj)r-S^!HgfkY{T z8)Pb(KrR)*Ee0CoDycxCRtTgbu|O(T!L1g^C2&h6AOk;25!_&_M7$jIa7$%UNv>KU zFA^6@bR}AaOj@MWDV35!QK3j7QcKkmty=A__<)+ZtNoY7fvMAcn>aw4o8tgUHC5(L zlVxm?874FbdRPg?C1s&0@3HzyjQa0*~ zXr%Mfi<*3 z08uM|NEavsN`XqC763G2u|O;lh@}FtOaM^~Mq;G^LS6#4Fc4rIzz~tcXn|mdaRK3; zTcl7F%8O)TxmK!Gi{(WMh;N-p27^Q{Etbo)?#>+0V}Esw_pM!Ty+G_!-yH3IDh&~B z6*i-(K$<7KmDnQ&`_*MSU6tL|V78bF9M!`M`DMjAg;=dnWJ_`&jBjb@v+=HB4?phU zm!+`pr{zuaf8X-xuO#{#_*Z)M^5rkY3lQI|A1>eccxnA`c>&^^^~2>GA1|#RE-yfQ zvwpaIn4# zhs!rUURpm~UV!*!{c!ol$4l#n%L@?StRF7l_;_jkaCrgZoAtxx8y_#NA1*IIe6xPI zeBxauX zK3-ZsTwZ|qX8mya#>Y$Rhsz5P->e@l-}rcG{cw2!;+yruscJqseNRMrbJEgeD%+AgmU%V|vVrIj~lE+A$N*25g$!$9IG!c<<>U zC=4^=E+2A&XG03-)Nj(p5n6O|-DMrr$9EF7j_%{*iMn1T_y8h>#8pO`>tuT%DuK9g z!uA?Lmtw+(2GCd_rMa|j$?D}R`Xmz2;MjObdu>p?aV)!ELiqd{cnlDLmfY$hUqtF# zX?l9@L`PtOTw@psBM}^l;9RwJVJ9LaWE^)RkLr%vgHWLoc^HHQp#?J1FxTxy9`!PY z_4h;!V#zv4++`phB$#5Z7pt|j|{3Cn|k$# zr#awMxXDpxDR%&e4=9I9=s+9>H=SV0iadPN8|}8X)&U}#jX1e%vbMEA9#(M;^6ol{ z41AEj&1oBMvYPDZ7%&JhbcEP#9OyDe5~L|>Y2?G>-`##P9HXx-9$O1Vxxq!?50q3m z8chQvG`+=Ht8W}23pSV_pQ+PX<|wVLD6faFA0UT}Uhx3qfF_%Ly4GTDw7MG~;%a

{%+vUG-c%K5YV0YQ92B<)!1?4`Se2&{sAxsA<*>(M{7k*3F;#Zj#}~2nJbqkA_bU#I^pWQW7(xu ze7=Y7&yZ|Gs~u3rtH4-lgfC+N-37Fz!`X`DsMg&2W<-xPrvO#_Qd5V;QJ?n9lApn_kS+|{_Mu06B2c_|d?v+gGUOmY`>sI^`Ydlx zc$Ale%IiA|$S-mYVLpm#1Dthjv-4r4VKDKty@U8)&gfAsk9r8IO${crqA~I7Aj-_v zM(A#<(M){t#cUmLV$s9HznIO#10r2<4FqT19~gI14i@?$7bAar5TkII7uCv7XJ$W0soamCb39dQXDCjBqXUw zTGB{TE$MDjBWWsWI;o5F2x%E<4e15aHqsu_2c+YqGo)`w*T@)|Nsb^Vkh94uvW{Fy z9#3u{+sQM@3&=~!Ysj0)JIVXW$H-^Mm&m_RXcP{GPsyg_Qc5YKDF(_^%1p|`logcc zDcdOfD90#gDOV_eP=lzk)GVroT1Fj9ZKQTk=Tnzb*HgDr-=!X>o~QmqqtPO0X*4CR zls1kwg?2CPVcJu)EwtUVBeZk0Yjiq2nw~|^r&rSTbSHg2eL4LF`rGuQ^z-ze8B7L` zAz_p-#xtypxs0WZjf}S#M;R9wHv&QfQUWvql>x?pX#tA@)&=Yg_%Psnz>Pq5U|L{) zU~S-(z&U}-0yhV~8+bbKDwD}fWU85?m}cf|<}&6>%=ejRnZK~YSeYyxYa*+S^$6=Z z)^64(tgAsmL8(E*g2o3qgB}Um5cE#a=RrRQbAoe%%Yu!;vw~L!Zwo#ed^sc_Bqc-} za!<(gkfkB7hI|-uDKsE7HB=X>51kphGW7M(lcCqx9JZKU$!=jk%-+a8z`htp4@(Uz z4l{;zg{=*HC+r-D%t_+tI0nxBoOPUcIp?`FZW_0YJB7QD`y%%c_eywJxGcObyfb`d z_?zKpBFGV`5oHmUh(!^vM4X8DH8L(z8)=GsC~|Y;(a7sjL!yR7nW7d%ZHYP_^=mXg zx;VNy`myNk(VxXoVlrb!#dO3x9rJF?r6JrQxkC&?77Tf1$fvQS*v#1K*n4Bw#vY8l z78f5kJgzlvdE7g3m*OMhhs95cUlRXT{8u~#fX{lpUA4uJvdND03tt@SN+NQMA=|Sm3)2F7dN&hH=mZ8dM&Uh;0a3(2Jp4pVS zGV{YMQkEjiob^=J5djs>nOg;G1Shju+1l*(>`mEcb0TuebLQr3&$%p27LFG_CfqOl zLnIejMC(MS#9`tQ;<@6T;vXcL5`$!=b+n(R`Pio!gwdG52C# zTAnFyUEaC;#C(1J>ijbW{DR2^&lH>)nlMy9bj{E&h9wO%4qHF$f;K}tMf-yGGJL(k zUbwaJx=y3JPq({>Tr|9BLD8Y&u;S6hD~dlaNi1nB*;I06xP17%!*`cbOGlPIR(i55 zuFO!jq3p^C<%s)6>>J4%Su=9Q$S=w>%kAYmD@YY1Di&9qzANP}>s{L`vC6W_#g(5` zrBzL>dSeuARMn`JqrR*bSI?;4U&E=HRI{<>r`p2WMYX3!r;lzMy|*r;Zerbry6a<# z#&nN4GgdhEzOf&Siy3Dgw_`kgeBJo<ZcOSSX<{ryE zZ%zuCq@VQaWa{KGlQ&NOO<$>BqrX;PR{v!E6@$+3gy9?GFyj*ASEhVZx9LJdenWS| z#m4-`#f@Jz4Q*Q5bjhqUuP}cmoEJ6VZ+0J|C{)4%l_8$NW&wC7AY1z{V45G>!T+g8~WJu-R$n^-RBlpEZ(++ zzhuFZA0MCe_<^OerK_F@e4_1%Gt0`C?O2|?{L$sVt!P?td}ZOvElG1pD{o4@#^8Lx2;KCvve(OZTs3U*VV1t|E%iS4eMjpFI@lobJpk1 zJYW6%z75I^8#cynT(pU_scq9&FHC&l@QXz+?%15YdG(fvEel`5UTS;k>z60LeBzan zuk3wQ_3Gx=QeJy7|u-W~bw`|p*!_s)Lp{S0ET4S;Y5S))PR%||J-y(w(9f2B9{c&4|H=5D zEoT&G-aK1$_TU#aUz|E;IQPvz9sm68eAkyjUoO4CyRhM+tWqjz8Zb?xgTXe?!8uZ?em{ne!6je!Ozh@ zKmUvBm;Jwv`Srq$j^F6NE&Dy=_nm)?{Nr>_OHU8+TZ2oi2GC-_^}8Rfpj~Tlw4UI* z@5%0;BPuKk!+SpNIfI3cC@Cw!a1sVPNAQcJ=Ua?Le7J6st^zDBW5EQ68E1nByyq0w zg|Qe6MgW5q5Wr$H1DWjb5Ed&WJc`2!=WwFfEaGxMT#R>$2QisJ!9k(H!J*vX;9xFF zg1N3N>_6k6XE(-XK$G}nJP{+YaWWh4`3!ahNIm=Tp-@XIELGrw3Zsh*jiXR$bVfiR z6E?^ODshZN?p20jI0Yw@C?qPK#-Nf}Qc$wVl!P!bRXa-0Nt`-ILgPNR`sKo;qPX+|`n_CF|zB z_V~V!{`upxTi-o?{#so_`~0Qrx4n1b%b%3P$24|4@WgZ5_n*9QosE%5P+JO7CpwKP zC#sMj4x>N~rY3Tzk~xoYQ4RJ~AGsn;u0Ly^+pVh!H#lV9r_fLZ=&AC(N1+mHBaOwQ z6;9I^eO0)94bu9n(DNzAA`@k@v7y+t+U~NHjO6aJ%AUg>^e05TB@p0_hLk`$1k++h z%!bv&77-s7wM{@f;dT&IE0}QxvEXAmtOk=Ihpu1AiKqlTr=kMO1cHIl@i5{WmuQz0 z!((90i%c=B9v{+2Pr=jOHW1LbnAk=_yIgi$LeOZGJo%ClO^{69iSGA4UGGq|hAR#bVO>nU-4R+XDAo|{;&An}B zrDGWLx1Qg7bM`$c#I7~O5L_g}8unljjeJ|-tCBqskN_dE-%qCOcn@ z{8-wosBS1G=~y}Juup@*W5@Vt--pm!9d^)BEc$77f}dtKA|7s{9tKOj1@Wj8klt)< z=ydA|zS-Jr^W-g#)`kJR!Gin`z|GOrg32g`o7hn|v^ktWqYDkqeheAtQ?Kabq98>T z2!L9e?6vR#Eu*ciUVE%+*X3O)ZxHop=(M930Lpv2iw_Du=0bfgVKkTUI+s9wE^3_% z^*~Vm%cx5T6mN&RWKh(}DF1&q>Tf1=vL|r;4>co2HzZ~@} zqw$_UhdRuzclLL-=g$6MT-|96u(Nmc=dZz8^cEwL$y6FGAdnRl!e)nYIAQG2kYE-w z0M>mJvjZ@qW^qNU4MJh6D;Y-iJi z3avaVA%+ti!ih=DQtC!cw$A+9@^zbDdg;aIRxO_2-Z*YVzBn~5A~Y1Ti}OcLu-x~^ zQ!i|Pd*6F|cfGvs@p;brnj%G3LUb5Aik~6Z)fn3!T=~Kq?;kn&@$o}@Ut8Bb%QAjs zo-la`H!M0aTU|PK%FM;^uZnL7EN!cEs|%%M{;9R#07Uvc0RP~wF9TV{_)ovKY#bd(YH4)o@uTt zR%G#``t@56oc`w8jo*K{at`!MW=JVYB%@Q4il%wasl3SnRb-H`M`=zJNF+saq`$d_P(;_(fgXm zjmXVOis6KW$0m#NMvQNs@$kxx+unL--=3W>tzFV(udmk0GkH;AK~O-ZLRU4(I%DCo zH5)f?d2#(y-Cb=BV@KqQQexp(VQ55LicnKhJJ~vY-XlwvFMpzY!7NAPxQd~&41RQ2 z5QI+@KV6(Vyyl)J`}EoOcg?-8-D((Hu2l+>AUl)J4B^HkWJq$0E5}Z1Xtr8g%!Uay zBeaU_l=w(C1R#SI3IUcOR%=TuM~@vpVSL@F@}fK$s8M(^sB|I%`Dr;a4T|5g(qe6% zQkYt{$cB%i!heaBQejqVLTnTYZ#oPhFbE3eM#b`zQZq6If~?H+ zl!UnG@UUQJ02+WKWWWkxb0cG7dHlqL1b+OG=m<_I3{V;s)M$j#1DMDnJTfXeDk?I9 z8wOe!;1u|e{a^4F{Ljw>|Nmgv%Rj#^s@H8DCRw4<*j`oXZ<*(&Y^{>+%Mhc6o!%yS%|B zUfy6cFK@7^mp9nl%NuO+<44gIiC)yuoH*-e6NOw8Hls%o}VH z<_$Ir^9GxSd4tWvyul`7-e5B^1g-C>m^av54CBK0WDG;k_iWrlit{}kgMsh)_ - -// A simple Particle class - -class Particle { - PVector location; - PVector velocity; - PVector acceleration; - float lifespan; - - Particle(PVector l) { - acceleration = new PVector(0, 0.05); - velocity = new PVector(random(-1, 1), random(-1, 0)); - location = l.get(); - lifespan = 255.0; - } - - void run() { - update(); - display(); - } - - // Method to update location - void update() { - velocity.add(acceleration); - location.add(velocity); - lifespan -= 2.0; - } - - // Method to display - void display() { - stroke(0, lifespan); - strokeWeight(2); - fill(127, lifespan); - ellipse(location.x, location.y, 12, 12); - } - - // Is the particle still useful? - boolean isDead() { - if (lifespan < 0.0) { - return true; - } - else { - return false; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_01_SingleParticle/_4_01_SingleParticle.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_01_SingleParticle/_4_01_SingleParticle.pde deleted file mode 100644 index 32f48596e..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_01_SingleParticle/_4_01_SingleParticle.pde +++ /dev/null @@ -1,21 +0,0 @@ -Particle p; - -void setup() { - size(800,200); - p = new Particle(new PVector(width/2,20)); - background(255); - smooth(); -} - -void draw() { - background(255); - - p.run(); - if (p.isDead()) { - p = new Particle(new PVector(width/2,20)); - //println("Particle dead!"); - } -} - - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_01_SingleParticle_trail/Particle.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_01_SingleParticle_trail/Particle.pde deleted file mode 100644 index 815931e27..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_01_SingleParticle_trail/Particle.pde +++ /dev/null @@ -1,49 +0,0 @@ -// Simple Particle System -// Daniel Shiffman - -// A simple Particle class - -class Particle { - PVector location; - PVector velocity; - PVector acceleration; - float lifespan; - - Particle(PVector l) { - acceleration = new PVector(0, 0.05); - velocity = new PVector(random(-1, 1), -1); - location = l.get(); - lifespan = 255.0; - } - - void run() { - update(); - display(); - } - - // Method to update location - void update() { - velocity.add(acceleration); - location.add(velocity); - lifespan -= 2.0; - } - - // Method to display - void display() { - stroke(0, lifespan); - strokeWeight(2); - fill(127); - ellipse(location.x, location.y, 12, 12); - } - - // Is the particle still useful? - boolean isDead() { - if (lifespan < 0.0) { - return true; - } - else { - return false; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_01_SingleParticle_trail/_4_01_SingleParticle_trail.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_01_SingleParticle_trail/_4_01_SingleParticle_trail.pde deleted file mode 100644 index 5548fb796..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_01_SingleParticle_trail/_4_01_SingleParticle_trail.pde +++ /dev/null @@ -1,23 +0,0 @@ -Particle p; - -void setup() { - size(800, 200); - p = new Particle(new PVector(width/2, 20)); - background(255); - smooth(); -} - -void draw() { - if (mousePressed) { - noStroke(); - fill(255, 5); - rect(0, 0, width, height); - - p.run(); - if (p.isDead()) { - println("Particle dead!"); - } - } -} - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_02_ArrayListParticles/Particle.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_02_ArrayListParticles/Particle.pde deleted file mode 100644 index 17a447011..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_02_ArrayListParticles/Particle.pde +++ /dev/null @@ -1,49 +0,0 @@ -// Simple Particle System -// Daniel Shiffman - -// A simple Particle class - -class Particle { - PVector location; - PVector velocity; - PVector acceleration; - float lifespan; - - Particle(PVector l) { - acceleration = new PVector(0, 0.05); - velocity = new PVector(random(-1, 1), random(-2, 0)); - location = l.get(); - lifespan = 255.0; - } - - void run() { - update(); - display(); - } - - // Method to update location - void update() { - velocity.add(acceleration); - location.add(velocity); - lifespan -= 2.0; - } - - // Method to display - void display() { - stroke(0, lifespan); - strokeWeight(2); - fill(127, lifespan); - ellipse(location.x, location.y, 12, 12); - } - - // Is the particle still useful? - boolean isDead() { - if (lifespan < 0.0) { - return true; - } - else { - return false; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_02_ArrayListParticles/_4_02_ArrayListParticles.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_02_ArrayListParticles/_4_02_ArrayListParticles.pde deleted file mode 100644 index 09d201c07..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_02_ArrayListParticles/_4_02_ArrayListParticles.pde +++ /dev/null @@ -1,27 +0,0 @@ -ArrayList particles; - -void setup() { - size(800,200); - particles = new ArrayList(); - smooth(); -} - -void draw() { - background(255); - - particles.add(new Particle(new PVector(width/2,50))); - - // Using the iterator - Iterator it = particles.iterator(); - while (it.hasNext()) { - Particle p = it.next(); - p.run(); - if (p.isDead()) { - it.remove(); - } - } -} - - - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_03_ParticleSystemClass/Particle.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_03_ParticleSystemClass/Particle.pde deleted file mode 100644 index a019abea2..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_03_ParticleSystemClass/Particle.pde +++ /dev/null @@ -1,49 +0,0 @@ -// Simple Particle System -// Daniel Shiffman - -// A simple Particle class - -class Particle { - PVector location; - PVector velocity; - PVector acceleration; - float lifespan; - - Particle(PVector l) { - acceleration = new PVector(0,0.05); - velocity = new PVector(random(-1,1),random(-2,0)); - location = l.get(); - lifespan = 255.0; - } - - void run() { - update(); - display(); - } - - // Method to update location - void update() { - velocity.add(acceleration); - location.add(velocity); - lifespan -= 2.0; - } - - // Method to display - void display() { - stroke(0,lifespan); - strokeWeight(2); - fill(127,lifespan); - ellipse(location.x,location.y,12,12); - } - - // Is the particle still useful? - boolean isDead() { - if (lifespan < 0.0) { - return true; - } else { - return false; - } - } -} - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_03_ParticleSystemClass/ParticleSystem.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_03_ParticleSystemClass/ParticleSystem.pde deleted file mode 100644 index 0df577d0e..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_03_ParticleSystemClass/ParticleSystem.pde +++ /dev/null @@ -1,31 +0,0 @@ -// Using Generics now! comment and annotate, etc. - -class ParticleSystem { - ArrayList particles; - PVector origin; - - ParticleSystem(PVector location) { - origin = location.get(); - particles = new ArrayList(); - } - - void addParticle() { - particles.add(new Particle(origin)); - } - - void run() { - Iterator it = particles.iterator(); - while (it.hasNext()) { - Particle p = it.next(); - p.run(); - if (p.isDead()) { - it.remove(); - } - } - } -} - - - - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_03_ParticleSystemClass/_4_03_ParticleSystemClass.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_03_ParticleSystemClass/_4_03_ParticleSystemClass.pde deleted file mode 100644 index a896b7f99..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_03_ParticleSystemClass/_4_03_ParticleSystemClass.pde +++ /dev/null @@ -1,13 +0,0 @@ -ParticleSystem ps; - -void setup() { - size(800,200); - smooth(); - ps = new ParticleSystem(new PVector(width/2,50)); -} - -void draw() { - background(255); - ps.addParticle(); - ps.run(); -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems/Particle.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems/Particle.pde deleted file mode 100644 index a019abea2..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems/Particle.pde +++ /dev/null @@ -1,49 +0,0 @@ -// Simple Particle System -// Daniel Shiffman - -// A simple Particle class - -class Particle { - PVector location; - PVector velocity; - PVector acceleration; - float lifespan; - - Particle(PVector l) { - acceleration = new PVector(0,0.05); - velocity = new PVector(random(-1,1),random(-2,0)); - location = l.get(); - lifespan = 255.0; - } - - void run() { - update(); - display(); - } - - // Method to update location - void update() { - velocity.add(acceleration); - location.add(velocity); - lifespan -= 2.0; - } - - // Method to display - void display() { - stroke(0,lifespan); - strokeWeight(2); - fill(127,lifespan); - ellipse(location.x,location.y,12,12); - } - - // Is the particle still useful? - boolean isDead() { - if (lifespan < 0.0) { - return true; - } else { - return false; - } - } -} - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems/ParticleSystem.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems/ParticleSystem.pde deleted file mode 100644 index 870908e47..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems/ParticleSystem.pde +++ /dev/null @@ -1,52 +0,0 @@ -// Simple Particle System -// Daniel Shiffman - -// A class to describe a group of Particles -// An ArrayList is used to manage the list of Particles - -class ParticleSystem { - - ArrayList particles; // An arraylist for all the particles - PVector origin; // An origin point for where particles are birthed - - ParticleSystem(int num, PVector v) { - particles = new ArrayList(); // Initialize the arraylist - origin = v.get(); // Store the origin point - for (int i = 0; i < num; i++) { - particles.add(new Particle(origin)); // Add "num" amount of particles to the arraylist - } - } - - void run() { - // Using the Iterator b/c we are deleting from list while iterating - Iterator it = particles.iterator(); - while (it.hasNext()) { - Particle p = it.next(); - p.run(); - if (p.isDead()) { - it.remove(); - } - } - } - - void addParticle() { - particles.add(new Particle(origin)); - } - - void addParticle(Particle p) { - particles.add(p); - } - - // A method to test if the particle system still has particles - boolean dead() { - if (particles.isEmpty()) { - return true; - } else { - return false; - } - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems/_4_04_SystemofSystems.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems/_4_04_SystemofSystems.pde deleted file mode 100644 index 6bfabb89d..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems/_4_04_SystemofSystems.pde +++ /dev/null @@ -1,30 +0,0 @@ -// Simple Particle System -// Daniel Shiffman - -// Particles are generated each cycle through draw(), -// fall with gravity and fade out over time -// A ParticleSystem object manages a variable size (ArrayList) -// list of particles. - -ArrayList systems; - -void setup() { - size(800,200); - systems = new ArrayList(); - smooth(); -} - -void draw() { - background(255); - for (ParticleSystem ps: systems) { - ps.run(); - ps.addParticle(); - } -} - -void mousePressed() { - systems.add(new ParticleSystem(1,new PVector(mouseX,mouseY))); -} - - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_b/Particle.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_b/Particle.pde deleted file mode 100644 index a019abea2..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_b/Particle.pde +++ /dev/null @@ -1,49 +0,0 @@ -// Simple Particle System -// Daniel Shiffman - -// A simple Particle class - -class Particle { - PVector location; - PVector velocity; - PVector acceleration; - float lifespan; - - Particle(PVector l) { - acceleration = new PVector(0,0.05); - velocity = new PVector(random(-1,1),random(-2,0)); - location = l.get(); - lifespan = 255.0; - } - - void run() { - update(); - display(); - } - - // Method to update location - void update() { - velocity.add(acceleration); - location.add(velocity); - lifespan -= 2.0; - } - - // Method to display - void display() { - stroke(0,lifespan); - strokeWeight(2); - fill(127,lifespan); - ellipse(location.x,location.y,12,12); - } - - // Is the particle still useful? - boolean isDead() { - if (lifespan < 0.0) { - return true; - } else { - return false; - } - } -} - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_b/ParticleSystem.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_b/ParticleSystem.pde deleted file mode 100644 index 870908e47..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_b/ParticleSystem.pde +++ /dev/null @@ -1,52 +0,0 @@ -// Simple Particle System -// Daniel Shiffman - -// A class to describe a group of Particles -// An ArrayList is used to manage the list of Particles - -class ParticleSystem { - - ArrayList particles; // An arraylist for all the particles - PVector origin; // An origin point for where particles are birthed - - ParticleSystem(int num, PVector v) { - particles = new ArrayList(); // Initialize the arraylist - origin = v.get(); // Store the origin point - for (int i = 0; i < num; i++) { - particles.add(new Particle(origin)); // Add "num" amount of particles to the arraylist - } - } - - void run() { - // Using the Iterator b/c we are deleting from list while iterating - Iterator it = particles.iterator(); - while (it.hasNext()) { - Particle p = it.next(); - p.run(); - if (p.isDead()) { - it.remove(); - } - } - } - - void addParticle() { - particles.add(new Particle(origin)); - } - - void addParticle(Particle p) { - particles.add(p); - } - - // A method to test if the particle system still has particles - boolean dead() { - if (particles.isEmpty()) { - return true; - } else { - return false; - } - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_b/_4_04_SystemofSystems_b.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_b/_4_04_SystemofSystems_b.pde deleted file mode 100644 index 70ec0bedc..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_b/_4_04_SystemofSystems_b.pde +++ /dev/null @@ -1,32 +0,0 @@ -// Simple Particle System -// Daniel Shiffman - -// Particles are generated each cycle through draw(), -// fall with gravity and fade out over time -// A ParticleSystem object manages a variable size (ArrayList) -// list of particles. - -ArrayList systems; - -void setup() { - size(800,200); - systems = new ArrayList(); - systems.add(new ParticleSystem(1,new PVector(100,25))); - - smooth(); -} - -void draw() { - background(255); - for (ParticleSystem ps: systems) { - ps.run(); - ps.addParticle(); - } -} - -void mousePressed() { - systems.add(new ParticleSystem(1,new PVector(mouseX,mouseY))); -} - - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_c/Particle.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_c/Particle.pde deleted file mode 100644 index a019abea2..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_c/Particle.pde +++ /dev/null @@ -1,49 +0,0 @@ -// Simple Particle System -// Daniel Shiffman - -// A simple Particle class - -class Particle { - PVector location; - PVector velocity; - PVector acceleration; - float lifespan; - - Particle(PVector l) { - acceleration = new PVector(0,0.05); - velocity = new PVector(random(-1,1),random(-2,0)); - location = l.get(); - lifespan = 255.0; - } - - void run() { - update(); - display(); - } - - // Method to update location - void update() { - velocity.add(acceleration); - location.add(velocity); - lifespan -= 2.0; - } - - // Method to display - void display() { - stroke(0,lifespan); - strokeWeight(2); - fill(127,lifespan); - ellipse(location.x,location.y,12,12); - } - - // Is the particle still useful? - boolean isDead() { - if (lifespan < 0.0) { - return true; - } else { - return false; - } - } -} - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_c/ParticleSystem.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_c/ParticleSystem.pde deleted file mode 100644 index 870908e47..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_c/ParticleSystem.pde +++ /dev/null @@ -1,52 +0,0 @@ -// Simple Particle System -// Daniel Shiffman - -// A class to describe a group of Particles -// An ArrayList is used to manage the list of Particles - -class ParticleSystem { - - ArrayList particles; // An arraylist for all the particles - PVector origin; // An origin point for where particles are birthed - - ParticleSystem(int num, PVector v) { - particles = new ArrayList(); // Initialize the arraylist - origin = v.get(); // Store the origin point - for (int i = 0; i < num; i++) { - particles.add(new Particle(origin)); // Add "num" amount of particles to the arraylist - } - } - - void run() { - // Using the Iterator b/c we are deleting from list while iterating - Iterator it = particles.iterator(); - while (it.hasNext()) { - Particle p = it.next(); - p.run(); - if (p.isDead()) { - it.remove(); - } - } - } - - void addParticle() { - particles.add(new Particle(origin)); - } - - void addParticle(Particle p) { - particles.add(p); - } - - // A method to test if the particle system still has particles - boolean dead() { - if (particles.isEmpty()) { - return true; - } else { - return false; - } - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_c/_4_04_SystemofSystems_c.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_c/_4_04_SystemofSystems_c.pde deleted file mode 100644 index dd84003d6..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_04_SystemofSystems_c/_4_04_SystemofSystems_c.pde +++ /dev/null @@ -1,35 +0,0 @@ -// Simple Particle System -// Daniel Shiffman - -// Particles are generated each cycle through draw(), -// fall with gravity and fade out over time -// A ParticleSystem object manages a variable size (ArrayList) -// list of particles. - -ArrayList systems; - -void setup() { - size(800,200); - systems = new ArrayList(); - systems.add(new ParticleSystem(1,new PVector(100,25))); - for (int i = 0; i < 6; i++) { - systems.add(new ParticleSystem(1,new PVector(random(width),random(height)))); - } - - smooth(); -} - -void draw() { - background(255); - for (ParticleSystem ps: systems) { - ps.run(); - ps.addParticle(); - } -} - -void mousePressed() { - systems.add(new ParticleSystem(1,new PVector(mouseX,mouseY))); -} - - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/Confetti.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/Confetti.pde deleted file mode 100644 index c0db00486..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/Confetti.pde +++ /dev/null @@ -1,25 +0,0 @@ -class Confetti extends Particle { - - // We could add variables for only Confetti here if we so - - Confetti(PVector l) { - super(l); - } - - // Inherits update() from parent - - // Override the display method - void display() { - rectMode(CENTER); - fill(127,lifespan); - stroke(0,lifespan); - strokeWeight(2); - pushMatrix(); - translate(location.x,location.y); - float theta = map(location.x,0,width,0,TWO_PI*2); - rotate(theta); - rect(0,0,12,12); - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/Particle.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/Particle.pde deleted file mode 100644 index e51908f50..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/Particle.pde +++ /dev/null @@ -1,50 +0,0 @@ -// Simple Particle System -// Daniel Shiffman - -// A simple Particle class - -class Particle { - - PVector location; - PVector velocity; - PVector acceleration; - float lifespan; - - Particle(PVector l) { - acceleration = new PVector(0,0.05); - velocity = new PVector(random(-1,1),random(-2,0)); - location = l.get(); - lifespan = 255.0; - } - - void run() { - update(); - display(); - } - - // Method to update location - void update() { - velocity.add(acceleration); - location.add(velocity); - lifespan -= 2.0; - } - - // Method to display - void display() { - stroke(0,lifespan); - strokeWeight(2); - fill(127,lifespan); - ellipse(location.x,location.y,12,12); - } - - // Is the particle still useful? - boolean isDead() { - if (lifespan < 0.0) { - return true; - } else { - return false; - } - } -} - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/ParticleSystem.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/ParticleSystem.pde deleted file mode 100644 index 8a5be1aaa..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/ParticleSystem.pde +++ /dev/null @@ -1,34 +0,0 @@ - -class ParticleSystem { - ArrayList particles; - PVector origin; - - ParticleSystem(PVector location) { - origin = location.get(); - particles = new ArrayList(); - } - - void addParticle() { - float r = random(1); - if (r < 0.5) { - particles.add(new Particle(origin)); - } else { - particles.add(new Confetti(origin)); - } - } - - void run() { - Iterator it = particles.iterator(); - while (it.hasNext()) { - Particle p = it.next(); - p.run(); - if (p.isDead()) { - it.remove(); - } - } - } -} - - - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/_4_05_ParticleSystemInheritancePolymorphism.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/_4_05_ParticleSystemInheritancePolymorphism.pde deleted file mode 100644 index a896b7f99..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/_4_05_ParticleSystemInheritancePolymorphism.pde +++ /dev/null @@ -1,13 +0,0 @@ -ParticleSystem ps; - -void setup() { - size(800,200); - smooth(); - ps = new ParticleSystem(new PVector(width/2,50)); -} - -void draw() { - background(255); - ps.addParticle(); - ps.run(); -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_06_ParticleSystemForces/Particle.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_06_ParticleSystemForces/Particle.pde deleted file mode 100644 index 120eb0e8c..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_06_ParticleSystemForces/Particle.pde +++ /dev/null @@ -1,57 +0,0 @@ -// Simple Particle System -// Daniel Shiffman - -// A simple Particle class - -class Particle { - PVector location; - PVector velocity; - PVector acceleration; - float lifespan; - - float mass = 1; // Let's do something better here! - - Particle(PVector l) { - acceleration = new PVector(0,0); - velocity = new PVector(random(-1,1),random(-2,0)); - location = l.get(); - lifespan = 255.0; - } - - void run() { - update(); - display(); - } - - void applyForce(PVector force) { - PVector f = force.get(); - f.div(mass); - acceleration.add(f); - } - - // Method to update location - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - lifespan -= 2.0; - } - - // Method to display - void display() { - stroke(0,lifespan); - strokeWeight(2); - fill(127,lifespan); - ellipse(location.x,location.y,12,12); - } - - // Is the particle still useful? - boolean isDead() { - if (lifespan < 0.0) { - return true; - } else { - return false; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_06_ParticleSystemForces/ParticleSystem.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_06_ParticleSystemForces/ParticleSystem.pde deleted file mode 100644 index 5f2223739..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_06_ParticleSystemForces/ParticleSystem.pde +++ /dev/null @@ -1,34 +0,0 @@ - -class ParticleSystem { - ArrayList particles; - PVector origin; - - ParticleSystem(PVector location) { - origin = location.get(); - particles = new ArrayList(); - } - - void addParticle() { - particles.add(new Particle(origin)); - } - - // A function to apply a force to all Particles - void applyForce(PVector f) { - for (Particle p: particles) { - p.applyForce(f); - } - } - - void run() { - Iterator it = particles.iterator(); - while (it.hasNext()) { - Particle p = it.next(); - p.run(); - if (p.isDead()) { - it.remove(); - } - } - } -} - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_06_ParticleSystemForces/_4_06_ParticleSystemForces.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_06_ParticleSystemForces/_4_06_ParticleSystemForces.pde deleted file mode 100644 index 266c12103..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_06_ParticleSystemForces/_4_06_ParticleSystemForces.pde +++ /dev/null @@ -1,18 +0,0 @@ -ParticleSystem ps; - -void setup() { - size(800,200); - smooth(); - ps = new ParticleSystem(new PVector(width/2,50)); -} - -void draw() { - background(255); - - // Apply gravity force to all Particles - PVector gravity = new PVector(0,0.1); - ps.applyForce(gravity); - - ps.addParticle(); - ps.run(); -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_07_ParticleSystemForcesRepeller/Particle.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_07_ParticleSystemForcesRepeller/Particle.pde deleted file mode 100644 index 120eb0e8c..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_07_ParticleSystemForcesRepeller/Particle.pde +++ /dev/null @@ -1,57 +0,0 @@ -// Simple Particle System -// Daniel Shiffman - -// A simple Particle class - -class Particle { - PVector location; - PVector velocity; - PVector acceleration; - float lifespan; - - float mass = 1; // Let's do something better here! - - Particle(PVector l) { - acceleration = new PVector(0,0); - velocity = new PVector(random(-1,1),random(-2,0)); - location = l.get(); - lifespan = 255.0; - } - - void run() { - update(); - display(); - } - - void applyForce(PVector force) { - PVector f = force.get(); - f.div(mass); - acceleration.add(f); - } - - // Method to update location - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - lifespan -= 2.0; - } - - // Method to display - void display() { - stroke(0,lifespan); - strokeWeight(2); - fill(127,lifespan); - ellipse(location.x,location.y,12,12); - } - - // Is the particle still useful? - boolean isDead() { - if (lifespan < 0.0) { - return true; - } else { - return false; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_07_ParticleSystemForcesRepeller/ParticleSystem.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_07_ParticleSystemForcesRepeller/ParticleSystem.pde deleted file mode 100644 index ba513bf62..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_07_ParticleSystemForcesRepeller/ParticleSystem.pde +++ /dev/null @@ -1,43 +0,0 @@ - -class ParticleSystem { - ArrayList particles; - PVector origin; - - ParticleSystem(PVector location) { - origin = location.get(); - particles = new ArrayList(); - } - - void addParticle() { - particles.add(new Particle(origin)); - } - - // A function to apply a force to all Particles - void applyForce(PVector f) { - for (Particle p: particles) { - p.applyForce(f); - } - } - - void applyRepeller(Repeller r) { - for (Particle p: particles) { - PVector force = r.repel(p); - p.applyForce(force); - } - } - - - void run() { - Iterator it = particles.iterator(); - while (it.hasNext()) { - Particle p = it.next(); - p.run(); - if (p.isDead()) { - it.remove(); - } - } - } -} - - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_07_ParticleSystemForcesRepeller/Repeller.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_07_ParticleSystemForcesRepeller/Repeller.pde deleted file mode 100644 index 973f55a89..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_07_ParticleSystemForcesRepeller/Repeller.pde +++ /dev/null @@ -1,36 +0,0 @@ -// Particles + Forces -// Daniel Shiffman - -// A very basic Repeller class -class Repeller { - - // Gravitational Constant - float G = 100; - // Location - PVector location; - float r = 10; - - Repeller(float x, float y) { - location = new PVector(x,y); - } - - void display() { - stroke(0); - strokeWeight(2); - fill(175); - ellipse(location.x,location.y,48,48); - } - - // Calculate a force to push particle away from repeller - PVector repel(Particle p) { - PVector dir = PVector.sub(location,p.location); // Calculate direction of force - float d = dir.mag(); // Distance between objects - dir.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction) - d = constrain(d,5,100); // Keep distance within a reasonable range - float force = -1 * G / (d * d); // Repelling force is inversely proportional to distance - dir.mult(force); // Get force vector --> magnitude * direction - return dir; - } -} - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_07_ParticleSystemForcesRepeller/_4_07_ParticleSystemForcesRepeller.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_07_ParticleSystemForcesRepeller/_4_07_ParticleSystemForcesRepeller.pde deleted file mode 100644 index 3450950b5..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_07_ParticleSystemForcesRepeller/_4_07_ParticleSystemForcesRepeller.pde +++ /dev/null @@ -1,23 +0,0 @@ -ParticleSystem ps; -Repeller repeller; - -void setup() { - size(800,200); - smooth(); - ps = new ParticleSystem(new PVector(width/2,50)); - repeller = new Repeller(width/2-20,height/2); -} - -void draw() { - background(255); - ps.addParticle(); - - // Apply gravity force to all Particles - PVector gravity = new PVector(0,0.1); - ps.applyForce(gravity); - - ps.applyRepeller(repeller); - - repeller.display(); - ps.run(); -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke/Particle.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke/Particle.pde deleted file mode 100644 index 709929f41..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke/Particle.pde +++ /dev/null @@ -1,64 +0,0 @@ -// Simple Particle System -// Daniel Shiffman - -// A simple Particle class, renders the particle as an image - -// Created 2 May 2005 - -class Particle { - PVector loc; - PVector vel; - PVector acc; - float lifespan; - PImage img; - - Particle(PVector l,PImage img_) { - acc = new PVector(0,0); - float vx = (float) generator.nextGaussian()*0.3; - float vy = (float) generator.nextGaussian()*0.3 - 1.0; - vel = new PVector(vx,vy); - loc = l.get(); - lifespan = 100.0; - img = img_; - } - - void run() { - update(); - render(); - } - - // Method to apply a force vector to the Particle object - // Note we are ignoring "mass" here - void applyForce(PVector f) { - acc.add(f); - } - - // Method to update location - void update() { - vel.add(acc); - loc.add(vel); - lifespan -= 2.5; - acc.mult(0); // clear Acceleration - } - - // Method to display - void render() { - imageMode(CENTER); - tint(255,lifespan); - image(img,loc.x,loc.y); - // Drawing a circle instead - // fill(255,lifespan); - // noStroke(); - // ellipse(loc.x,loc.y,img.width,img.height); - } - - // Is the particle still useful? - boolean dead() { - if (lifespan <= 0.0) { - return true; - } else { - return false; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke/ParticleSystem.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke/ParticleSystem.pde deleted file mode 100644 index e193f63c0..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke/ParticleSystem.pde +++ /dev/null @@ -1,62 +0,0 @@ -// Smoke Particle Syste -// Daniel Shiffman - -// A class to describe a group of Particles -// An ArrayList is used to manage the list of Particles - -class ParticleSystem { - - ArrayList particles; // An arraylist for all the particles - PVector origin; // An origin point for where particles are birthed - PImage img; - - ParticleSystem(int num, PVector v, PImage img_) { - particles = new ArrayList(); // Initialize the arraylist - origin = v.get(); // Store the origin point - img = img_; - for (int i = 0; i < num; i++) { - particles.add(new Particle(origin, img)); // Add "num" amount of particles to the arraylist - } - } - - void run() { - Iterator it = particles.iterator(); - while (it.hasNext()) { - Particle p = it.next(); - p.run(); - if (p.dead()) { - it.remove(); - } - } - } - - // Method to add a force vector to all particles currently in the system - void applyForce(PVector dir) { - // Enhanced loop!!! - for (Particle p: particles) { - p.applyForce(dir); - } - - } - - void addParticle() { - particles.add(new Particle(origin,img)); - } - - void addParticle(Particle p) { - particles.add(p); - } - - // A method to test if the particle system still has particles - boolean dead() { - if (particles.isEmpty()) { - return true; - } else { - return false; - } - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke/_4_08_ParticleSystemSmoke.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke/_4_08_ParticleSystemSmoke.pde deleted file mode 100644 index db907b374..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke/_4_08_ParticleSystemSmoke.pde +++ /dev/null @@ -1,54 +0,0 @@ -// Smoke Particle System -// Daniel Shiffman - -// A basic smoke effect using a particle system -// Each particle is rendered as an alpha masked image - -/* @pjs preload="processingjs/chapter04/_4_08_ParticleSystemSmoke/data/texture.png"; */ - -ParticleSystem ps; -Random generator; - -void setup() { - size(383,200); - generator = new Random(); - PImage img = loadImage("texture.png"); - ps = new ParticleSystem(0,new PVector(width/2,height-25),img); - smooth(); -} - -void draw() { - background(0); - - // Calculate a "wind" force based on mouse horizontal position - float dx = map(mouseX,0,width,-0.2,0.2); - PVector wind = new PVector(dx,0); - ps.applyForce(wind); - ps.run(); - for (int i = 0; i < 2; i++) { - ps.addParticle(); - } - - // Draw an arrow representing the wind force - drawVector(wind, new PVector(width/2,50,0),500); - -} - -// Renders a vector object 'v' as an arrow and a location 'loc' -void drawVector(PVector v, PVector loc, float scayl) { - pushMatrix(); - float arrowsize = 4; - // Translate to location to render vector - translate(loc.x,loc.y); - stroke(255); - // Call vector heading function to get direction (note that pointing up is a heading of 0) and rotate - rotate(v.heading2D()); - // Calculate length of vector & scale it to be bigger or smaller if necessary - float len = v.mag()*scayl; - // Draw three lines to make an arrow (draw pointing up since we've rotate to the proper direction) - line(0,0,len,0); - line(len,0,len-arrowsize,+arrowsize/2); - line(len,0,len-arrowsize,-arrowsize/2); - popMatrix(); -} - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke/data/texture.psd b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke/data/texture.psd deleted file mode 100644 index 8208feb020b9552dba21c52ff59db597e4172699..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26456 zcmeHP33yY*+CC?Hn{-K&uCz_MZ)vlyT_8 zMMV}-K*5bgL+Yna|_P#Y7676j&XYC2n5TTD(p zzq7?+b!a;C6ZJ-0y-5Q!5(^Xggo(2`KT(Sm{IL~Pe4Wj1;>&U*Ig)IHNFn9Rr8!c$ zL?Mw0_!5ywB@`)zQc<>8r4h+BGBMwMB^Cq%m1j3LXsU}!+yw%cpV;JdwrYgJj*gC; z4rz|f-Y68S)oP(gB9ut7!6Mr+&Fa*5W?LOeE+@TyicAiJ-Q4Ol+pK)#S6^>ybLJ-| zqJsJ^cgtE@`wFr;a)?&u7;G)VPJOFToFfwUd4`O6fQm+EH|d==d#%l8DR8yDs>$ZG zIht&(d|i!VR*Tu7M_n##w;J6Y+1lGP zdBT3vzq;1Y%M}%U6~AQ=wX_It6?_h7aXZANJI-&J(@{IE)g-JoIc#lqgQ>V3aOe+q zcSu%LXv(Y(r`~EXl@%30b#lyRqei4vK~O1WBBey6P>ID_rC6>5iBzf3sYR+nBC-Z% z9T*d!E3z5d5cF=hM&wrd=iGW^y~%B*-3%`yy~V=@)%yS9{uVB7DyG!zfPp%#HyT|d zpNPpC)6{{|-e9$ui5P9w+Z`r^e12jt^q%hlmnW2m=s}I%fa0#efZhxyW1et;w7**3 z+03`-v_a8z`S!?qd;c9xCabSEi^~;Zb$cfcTZ6MhZ#QWhAr1z6;ki5x%;N3Z^|r8> z{|z1B(6`?q{DY2}JAvQpmHeN9zdvdXO?qpi$ygxl4cK16pX)JKKMov8z3&vSk@uHP z5KePL|GHqn`x0qxp0ANq1Fs4QU1Dk|5a$VRlJz$?kI;=pL*CLx3~6|G!X*@=)ScB+ z?VWX;@2s9`@2vefM_bL#0*SjcFR^#7yP#R^rXq8r$pLxf3V}qfgj)r-S^!HgfkY{T z8)Pb(KrR)*Ee0CoDycxCRtTgbu|O(T!L1g^C2&h6AOk;25!_&_M7$jIa7$%UNv>KU zFA^6@bR}AaOj@MWDV35!QK3j7QcKkmty=A__<)+ZtNoY7fvMAcn>aw4o8tgUHC5(L zlVxm?874FbdRPg?C1s&0@3HzyjQa0*~ zXr%Mfi<*3 z08uM|NEavsN`XqC763G2u|O;lh@}FtOaM^~Mq;G^LS6#4Fc4rIzz~tcXn|mdaRK3; zTcl7F%8O)TxmK!Gi{(WMh;N-p27^Q{Etbo)?#>+0V}Esw_pM!Ty+G_!-yH3IDh&~B z6*i-(K$<7KmDnQ&`_*MSU6tL|V78bF9M!`M`DMjAg;=dnWJ_`&jBjb@v+=HB4?phU zm!+`pr{zuaf8X-xuO#{#_*Z)M^5rkY3lQI|A1>eccxnA`c>&^^^~2>GA1|#RE-yfQ zvwpaIn4# zhs!rUURpm~UV!*!{c!ol$4l#n%L@?StRF7l_;_jkaCrgZoAtxx8y_#NA1*IIe6xPI zeBxauX zK3-ZsTwZ|qX8mya#>Y$Rhsz5P->e@l-}rcG{cw2!;+yruscJqseNRMrbJEgeD%+AgmU%V|vVrIj~lE+A$N*25g$!$9IG!c<<>U zC=4^=E+2A&XG03-)Nj(p5n6O|-DMrr$9EF7j_%{*iMn1T_y8h>#8pO`>tuT%DuK9g z!uA?Lmtw+(2GCd_rMa|j$?D}R`Xmz2;MjObdu>p?aV)!ELiqd{cnlDLmfY$hUqtF# zX?l9@L`PtOTw@psBM}^l;9RwJVJ9LaWE^)RkLr%vgHWLoc^HHQp#?J1FxTxy9`!PY z_4h;!V#zv4++`phB$#5Z7pt|j|{3Cn|k$# zr#awMxXDpxDR%&e4=9I9=s+9>H=SV0iadPN8|}8X)&U}#jX1e%vbMEA9#(M;^6ol{ z41AEj&1oBMvYPDZ7%&JhbcEP#9OyDe5~L|>Y2?G>-`##P9HXx-9$O1Vxxq!?50q3m z8chQvG`+=Ht8W}23pSV_pQ+PX<|wVLD6faFA0UT}Uhx3qfF_%Ly4GTDw7MG~;%a

{%+vUG-c%K5YV0YQ92B<)!1?4`Se2&{sAxsA<*>(M{7k*3F;#Zj#}~2nJbqkA_bU#I^pWQW7(xu ze7=Y7&yZ|Gs~u3rtH4-lgfC+N-37Fz!`X`DsMg&2W<-xPrvO#_Qd5V;QJ?n9lApn_kS+|{_Mu06B2c_|d?v+gGUOmY`>sI^`Ydlx zc$Ale%IiA|$S-mYVLpm#1Dthjv-4r4VKDKty@U8)&gfAsk9r8IO${crqA~I7Aj-_v zM(A#<(M){t#cUmLV$s9HznIO#10r2<4FqT19~gI14i@?$7bAar5TkII7uCv7XJ$W0soamCb39dQXDCjBqXUw zTGB{TE$MDjBWWsWI;o5F2x%E<4e15aHqsu_2c+YqGo)`w*T@)|Nsb^Vkh94uvW{Fy z9#3u{+sQM@3&=~!Ysj0)JIVXW$H-^Mm&m_RXcP{GPsyg_Qc5YKDF(_^%1p|`logcc zDcdOfD90#gDOV_eP=lzk)GVroT1Fj9ZKQTk=Tnzb*HgDr-=!X>o~QmqqtPO0X*4CR zls1kwg?2CPVcJu)EwtUVBeZk0Yjiq2nw~|^r&rSTbSHg2eL4LF`rGuQ^z-ze8B7L` zAz_p-#xtypxs0WZjf}S#M;R9wHv&QfQUWvql>x?pX#tA@)&=Yg_%Psnz>Pq5U|L{) zU~S-(z&U}-0yhV~8+bbKDwD}fWU85?m}cf|<}&6>%=ejRnZK~YSeYyxYa*+S^$6=Z z)^64(tgAsmL8(E*g2o3qgB}Um5cE#a=RrRQbAoe%%Yu!;vw~L!Zwo#ed^sc_Bqc-} za!<(gkfkB7hI|-uDKsE7HB=X>51kphGW7M(lcCqx9JZKU$!=jk%-+a8z`htp4@(Uz z4l{;zg{=*HC+r-D%t_+tI0nxBoOPUcIp?`FZW_0YJB7QD`y%%c_eywJxGcObyfb`d z_?zKpBFGV`5oHmUh(!^vM4X8DH8L(z8)=GsC~|Y;(a7sjL!yR7nW7d%ZHYP_^=mXg zx;VNy`myNk(VxXoVlrb!#dO3x9rJF?r6JrQxkC&?77Tf1$fvQS*v#1K*n4Bw#vY8l z78f5kJgzlvdE7g3m*OMhhs95cUlRXT{8u~#fX{lpUA4uJvdND03tt@SN+NQMA=|Sm3)2F7dN&hH=mZ8dM&Uh;0a3(2Jp4pVS zGV{YMQkEjiob^=J5djs>nOg;G1Shju+1l*(>`mEcb0TuebLQr3&$%p27LFG_CfqOl zLnIejMC(MS#9`tQ;<@6T;vXcL5`$!=b+n(R`Pio!gwdG52C# zTAnFyUEaC;#C(1J>ijbW{DR2^&lH>)nlMy9bj{E&h9wO%4qHF$f;K}tMf-yGGJL(k zUbwaJx=y3JPq({>Tr|9BLD8Y&u;S6hD~dlaNi1nB*;I06xP17%!*`cbOGlPIR(i55 zuFO!jq3p^C<%s)6>>J4%Su=9Q$S=w>%kAYmD@YY1Di&9qzANP}>s{L`vC6W_#g(5` zrBzL>dSeuARMn`JqrR*bSI?;4U&E=HRI{<>r`p2WMYX3!r;lzMy|*r;Zerbry6a<# z#&nN4GgdhEzOf&Siy3Dgw_`kgeBJo<ZcOSSX<{ryE zZ%zuCq@VQaWa{KGlQ&NOO<$>BqrX;PR{v!E6@$+3gy9?GFyj*ASEhVZx9LJdenWS| z#m4-`#f@Jz4Q*Q5bjhqUuP}cmoEJ6VZ+0J|C{)4%l_8$NW&wC7AY1z{V45G>!T+g8~WJu-R$n^-RBlpEZ(++ zzhuFZA0MCe_<^OerK_F@e4_1%Gt0`C?O2|?{L$sVt!P?td}ZOvElG1pD{o4@#^8Lx2;KCvve(OZTs3U*VV1t|E%iS4eMjpFI@lobJpk1 zJYW6%z75I^8#cynT(pU_scq9&FHC&l@QXz+?%15YdG(fvEel`5UTS;k>z60LeBzan zuk3wQ_3Gx=QeJy7|u-W~bw`|p*!_s)Lp{S0ET4S;Y5S))PR%||J-y(w(9f2B9{c&4|H=5D zEoT&G-aK1$_TU#aUz|E;IQPvz9sm68eAkyjUoO4CyRhM+tWqjz8Zb?xgTXe?!8uZ?em{ne!6je!Ozh@ zKmUvBm;Jwv`Srq$j^F6NE&Dy=_nm)?{Nr>_OHU8+TZ2oi2GC-_^}8Rfpj~Tlw4UI* z@5%0;BPuKk!+SpNIfI3cC@Cw!a1sVPNAQcJ=Ua?Le7J6st^zDBW5EQ68E1nByyq0w zg|Qe6MgW5q5Wr$H1DWjb5Ed&WJc`2!=WwFfEaGxMT#R>$2QisJ!9k(H!J*vX;9xFF zg1N3N>_6k6XE(-XK$G}nJP{+YaWWh4`3!ahNIm=Tp-@XIELGrw3Zsh*jiXR$bVfiR z6E?^ODshZN?p20jI0Yw@C?qPK#-Nf}Qc$wVl!P!bRXa-0Nt`-ILgPNR`sKo;qPX+|`n_CF|zB z_V~V!{`upxTi-o?{#so_`~0Qrx4n1b%b%3P$24|4@WgZ5_n*9QosE%5P+JO7CpwKP zC#sMj4x>N~rY3Tzk~xoYQ4RJ~AGsn;u0Ly^+pVh!H#lV9r_fLZ=&AC(N1+mHBaOwQ z6;9I^eO0)94bu9n(DNzAA`@k@v7y+t+U~NHjO6aJ%AUg>^e05TB@p0_hLk`$1k++h z%!bv&77-s7wM{@f;dT&IE0}QxvEXAmtOk=Ihpu1AiKqlTr=kMO1cHIl@i5{WmuQz0 z!((90i%c=B9v{+2Pr=jOHW1LbnAk=_yIgi$LeOZGJo%ClO^{69iSGA4UGGq|hAR#bVO>nU-4R+XDAo|{;&An}B zrDGWLx1Qg7bM`$c#I7~O5L_g}8unljjeJ|-tCBqskN_dE-%qCOcn@ z{8-wosBS1G=~y}Juup@*W5@Vt--pm!9d^)BEc$77f}dtKA|7s{9tKOj1@Wj8klt)< z=ydA|zS-Jr^W-g#)`kJR!Gin`z|GOrg32g`o7hn|v^ktWqYDkqeheAtQ?Kabq98>T z2!L9e?6vR#Eu*ciUVE%+*X3O)ZxHop=(M930Lpv2iw_Du=0bfgVKkTUI+s9wE^3_% z^*~Vm%cx5T6mN&RWKh(}DF1&q>Tf1=vL|r;4>co2HzZ~@} zqw$_UhdRuzclLL-=g$6MT-|96u(Nmc=dZz8^cEwL$y6FGAdnRl!e)nYIAQG2kYE-w z0M>mJvjZ@qW^qNU4MJh6D;Y-iJi z3avaVA%+ti!ih=DQtC!cw$A+9@^zbDdg;aIRxO_2-Z*YVzBn~5A~Y1Ti}OcLu-x~^ zQ!i|Pd*6F|cfGvs@p;brnj%G3LUb5Aik~6Z)fn3!T=~Kq?;kn&@$o}@Ut8Bb%QAjs zo-la`H!M0aTU|PK%FM;^uZnL7EN!cEs|%%M{;9R#07Uvc0RP~wF9TV{_)ovKY#bd(YH4)o@uTt zR%G#``t@56oc`w8jo*K{at`!MW=JVYB%@Q4il%wasl3SnRb-H`M`=zJNF+saq`$d_P(;_(fgXm zjmXVOis6KW$0m#NMvQNs@$kxx+unL--=3W>tzFV(udmk0GkH;AK~O-ZLRU4(I%DCo zH5)f?d2#(y-Cb=BV@KqQQexp(VQ55LicnKhJJ~vY-XlwvFMpzY!7NAPxQd~&41RQ2 z5QI+@KV6(Vyyl)J`}EoOcg?-8-D((Hu2l+>AUl)J4B^HkWJq$0E5}Z1Xtr8g%!Uay zBeaU_l=w(C1R#SI3IUcOR%=TuM~@vpVSL@F@}fK$s8M(^sB|I%`Dr;a4T|5g(qe6% zQkYt{$cB%i!heaBQejqVLTnTYZ#oPhFbE3eM#b`zQZq6If~?H+ zl!UnG@UUQJ02+WKWWWkxb0cG7dHlqL1b+OG=m<_I3{V;s)M$j#1DMDnJTfXeDk?I9 z8wOe!;1u|e{a^4F{Ljw>|Nmgv%Rj#^s@H8DCRw4<*j`oXZ<*(&Y^{>+%Mhc6o!%yS%|B zUfy6cFK@7^mp9nl%NuO+<44gIiC)yuoH*-e6NOw8Hls%o}VH z<_$Ir^9GxSd4tWvyul`7-e5B^1g-C>m^av54CBK0WDG;k_iWrlit{}kgMsh)_ - -// A simple Particle class, renders the particle as an image - -// Created 2 May 2005 - -class Particle { - PVector loc; - PVector vel; - PVector acc; - float lifespan; - PImage img; - - Particle(PVector l,PImage img_) { - acc = new PVector(0,0); - float vx = (float) generator.nextGaussian()*0.3; - float vy = (float) generator.nextGaussian()*0.3 - 1.0; - vel = new PVector(vx,vy); - loc = l.get(); - lifespan = 100.0; - img = img_; - } - - void run() { - update(); - render(); - } - - // Method to apply a force vector to the Particle object - // Note we are ignoring "mass" here - void applyForce(PVector f) { - acc.add(f); - } - - // Method to update location - void update() { - vel.add(acc); - loc.add(vel); - lifespan -= 2.5; - acc.mult(0); // clear Acceleration - } - - // Method to display - void render() { - //imageMode(CENTER); - //tint(255,lifespan); - //image(img,loc.x,loc.y); - // Drawing a circle instead - fill(255,lifespan); - noStroke(); - ellipse(loc.x,loc.y,img.width,img.height); - } - - // Is the particle still useful? - boolean dead() { - if (lifespan <= 0.0) { - return true; - } else { - return false; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/ParticleSystem.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/ParticleSystem.pde deleted file mode 100644 index e193f63c0..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/ParticleSystem.pde +++ /dev/null @@ -1,62 +0,0 @@ -// Smoke Particle Syste -// Daniel Shiffman - -// A class to describe a group of Particles -// An ArrayList is used to manage the list of Particles - -class ParticleSystem { - - ArrayList particles; // An arraylist for all the particles - PVector origin; // An origin point for where particles are birthed - PImage img; - - ParticleSystem(int num, PVector v, PImage img_) { - particles = new ArrayList(); // Initialize the arraylist - origin = v.get(); // Store the origin point - img = img_; - for (int i = 0; i < num; i++) { - particles.add(new Particle(origin, img)); // Add "num" amount of particles to the arraylist - } - } - - void run() { - Iterator it = particles.iterator(); - while (it.hasNext()) { - Particle p = it.next(); - p.run(); - if (p.dead()) { - it.remove(); - } - } - } - - // Method to add a force vector to all particles currently in the system - void applyForce(PVector dir) { - // Enhanced loop!!! - for (Particle p: particles) { - p.applyForce(dir); - } - - } - - void addParticle() { - particles.add(new Particle(origin,img)); - } - - void addParticle(Particle p) { - particles.add(p); - } - - // A method to test if the particle system still has particles - boolean dead() { - if (particles.isEmpty()) { - return true; - } else { - return false; - } - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/_4_08_ParticleSystemSmoke_b.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/_4_08_ParticleSystemSmoke_b.pde deleted file mode 100644 index db907b374..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/_4_08_ParticleSystemSmoke_b.pde +++ /dev/null @@ -1,54 +0,0 @@ -// Smoke Particle System -// Daniel Shiffman - -// A basic smoke effect using a particle system -// Each particle is rendered as an alpha masked image - -/* @pjs preload="processingjs/chapter04/_4_08_ParticleSystemSmoke/data/texture.png"; */ - -ParticleSystem ps; -Random generator; - -void setup() { - size(383,200); - generator = new Random(); - PImage img = loadImage("texture.png"); - ps = new ParticleSystem(0,new PVector(width/2,height-25),img); - smooth(); -} - -void draw() { - background(0); - - // Calculate a "wind" force based on mouse horizontal position - float dx = map(mouseX,0,width,-0.2,0.2); - PVector wind = new PVector(dx,0); - ps.applyForce(wind); - ps.run(); - for (int i = 0; i < 2; i++) { - ps.addParticle(); - } - - // Draw an arrow representing the wind force - drawVector(wind, new PVector(width/2,50,0),500); - -} - -// Renders a vector object 'v' as an arrow and a location 'loc' -void drawVector(PVector v, PVector loc, float scayl) { - pushMatrix(); - float arrowsize = 4; - // Translate to location to render vector - translate(loc.x,loc.y); - stroke(255); - // Call vector heading function to get direction (note that pointing up is a heading of 0) and rotate - rotate(v.heading2D()); - // Calculate length of vector & scale it to be bigger or smaller if necessary - float len = v.mag()*scayl; - // Draw three lines to make an arrow (draw pointing up since we've rotate to the proper direction) - line(0,0,len,0); - line(len,0,len-arrowsize,+arrowsize/2); - line(len,0,len-arrowsize,-arrowsize/2); - popMatrix(); -} - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/data/texture.psd b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/data/texture.psd deleted file mode 100644 index 8208feb020b9552dba21c52ff59db597e4172699..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26456 zcmeHP33yY*+CC?Hn{-K&uCz_MZ)vlyT_8 zMMV}-K*5bgL+Yna|_P#Y7676j&XYC2n5TTD(p zzq7?+b!a;C6ZJ-0y-5Q!5(^Xggo(2`KT(Sm{IL~Pe4Wj1;>&U*Ig)IHNFn9Rr8!c$ zL?Mw0_!5ywB@`)zQc<>8r4h+BGBMwMB^Cq%m1j3LXsU}!+yw%cpV;JdwrYgJj*gC; z4rz|f-Y68S)oP(gB9ut7!6Mr+&Fa*5W?LOeE+@TyicAiJ-Q4Ol+pK)#S6^>ybLJ-| zqJsJ^cgtE@`wFr;a)?&u7;G)VPJOFToFfwUd4`O6fQm+EH|d==d#%l8DR8yDs>$ZG zIht&(d|i!VR*Tu7M_n##w;J6Y+1lGP zdBT3vzq;1Y%M}%U6~AQ=wX_It6?_h7aXZANJI-&J(@{IE)g-JoIc#lqgQ>V3aOe+q zcSu%LXv(Y(r`~EXl@%30b#lyRqei4vK~O1WBBey6P>ID_rC6>5iBzf3sYR+nBC-Z% z9T*d!E3z5d5cF=hM&wrd=iGW^y~%B*-3%`yy~V=@)%yS9{uVB7DyG!zfPp%#HyT|d zpNPpC)6{{|-e9$ui5P9w+Z`r^e12jt^q%hlmnW2m=s}I%fa0#efZhxyW1et;w7**3 z+03`-v_a8z`S!?qd;c9xCabSEi^~;Zb$cfcTZ6MhZ#QWhAr1z6;ki5x%;N3Z^|r8> z{|z1B(6`?q{DY2}JAvQpmHeN9zdvdXO?qpi$ygxl4cK16pX)JKKMov8z3&vSk@uHP z5KePL|GHqn`x0qxp0ANq1Fs4QU1Dk|5a$VRlJz$?kI;=pL*CLx3~6|G!X*@=)ScB+ z?VWX;@2s9`@2vefM_bL#0*SjcFR^#7yP#R^rXq8r$pLxf3V}qfgj)r-S^!HgfkY{T z8)Pb(KrR)*Ee0CoDycxCRtTgbu|O(T!L1g^C2&h6AOk;25!_&_M7$jIa7$%UNv>KU zFA^6@bR}AaOj@MWDV35!QK3j7QcKkmty=A__<)+ZtNoY7fvMAcn>aw4o8tgUHC5(L zlVxm?874FbdRPg?C1s&0@3HzyjQa0*~ zXr%Mfi<*3 z08uM|NEavsN`XqC763G2u|O;lh@}FtOaM^~Mq;G^LS6#4Fc4rIzz~tcXn|mdaRK3; zTcl7F%8O)TxmK!Gi{(WMh;N-p27^Q{Etbo)?#>+0V}Esw_pM!Ty+G_!-yH3IDh&~B z6*i-(K$<7KmDnQ&`_*MSU6tL|V78bF9M!`M`DMjAg;=dnWJ_`&jBjb@v+=HB4?phU zm!+`pr{zuaf8X-xuO#{#_*Z)M^5rkY3lQI|A1>eccxnA`c>&^^^~2>GA1|#RE-yfQ zvwpaIn4# zhs!rUURpm~UV!*!{c!ol$4l#n%L@?StRF7l_;_jkaCrgZoAtxx8y_#NA1*IIe6xPI zeBxauX zK3-ZsTwZ|qX8mya#>Y$Rhsz5P->e@l-}rcG{cw2!;+yruscJqseNRMrbJEgeD%+AgmU%V|vVrIj~lE+A$N*25g$!$9IG!c<<>U zC=4^=E+2A&XG03-)Nj(p5n6O|-DMrr$9EF7j_%{*iMn1T_y8h>#8pO`>tuT%DuK9g z!uA?Lmtw+(2GCd_rMa|j$?D}R`Xmz2;MjObdu>p?aV)!ELiqd{cnlDLmfY$hUqtF# zX?l9@L`PtOTw@psBM}^l;9RwJVJ9LaWE^)RkLr%vgHWLoc^HHQp#?J1FxTxy9`!PY z_4h;!V#zv4++`phB$#5Z7pt|j|{3Cn|k$# zr#awMxXDpxDR%&e4=9I9=s+9>H=SV0iadPN8|}8X)&U}#jX1e%vbMEA9#(M;^6ol{ z41AEj&1oBMvYPDZ7%&JhbcEP#9OyDe5~L|>Y2?G>-`##P9HXx-9$O1Vxxq!?50q3m z8chQvG`+=Ht8W}23pSV_pQ+PX<|wVLD6faFA0UT}Uhx3qfF_%Ly4GTDw7MG~;%a

{%+vUG-c%K5YV0YQ92B<)!1?4`Se2&{sAxsA<*>(M{7k*3F;#Zj#}~2nJbqkA_bU#I^pWQW7(xu ze7=Y7&yZ|Gs~u3rtH4-lgfC+N-37Fz!`X`DsMg&2W<-xPrvO#_Qd5V;QJ?n9lApn_kS+|{_Mu06B2c_|d?v+gGUOmY`>sI^`Ydlx zc$Ale%IiA|$S-mYVLpm#1Dthjv-4r4VKDKty@U8)&gfAsk9r8IO${crqA~I7Aj-_v zM(A#<(M){t#cUmLV$s9HznIO#10r2<4FqT19~gI14i@?$7bAar5TkII7uCv7XJ$W0soamCb39dQXDCjBqXUw zTGB{TE$MDjBWWsWI;o5F2x%E<4e15aHqsu_2c+YqGo)`w*T@)|Nsb^Vkh94uvW{Fy z9#3u{+sQM@3&=~!Ysj0)JIVXW$H-^Mm&m_RXcP{GPsyg_Qc5YKDF(_^%1p|`logcc zDcdOfD90#gDOV_eP=lzk)GVroT1Fj9ZKQTk=Tnzb*HgDr-=!X>o~QmqqtPO0X*4CR zls1kwg?2CPVcJu)EwtUVBeZk0Yjiq2nw~|^r&rSTbSHg2eL4LF`rGuQ^z-ze8B7L` zAz_p-#xtypxs0WZjf}S#M;R9wHv&QfQUWvql>x?pX#tA@)&=Yg_%Psnz>Pq5U|L{) zU~S-(z&U}-0yhV~8+bbKDwD}fWU85?m}cf|<}&6>%=ejRnZK~YSeYyxYa*+S^$6=Z z)^64(tgAsmL8(E*g2o3qgB}Um5cE#a=RrRQbAoe%%Yu!;vw~L!Zwo#ed^sc_Bqc-} za!<(gkfkB7hI|-uDKsE7HB=X>51kphGW7M(lcCqx9JZKU$!=jk%-+a8z`htp4@(Uz z4l{;zg{=*HC+r-D%t_+tI0nxBoOPUcIp?`FZW_0YJB7QD`y%%c_eywJxGcObyfb`d z_?zKpBFGV`5oHmUh(!^vM4X8DH8L(z8)=GsC~|Y;(a7sjL!yR7nW7d%ZHYP_^=mXg zx;VNy`myNk(VxXoVlrb!#dO3x9rJF?r6JrQxkC&?77Tf1$fvQS*v#1K*n4Bw#vY8l z78f5kJgzlvdE7g3m*OMhhs95cUlRXT{8u~#fX{lpUA4uJvdND03tt@SN+NQMA=|Sm3)2F7dN&hH=mZ8dM&Uh;0a3(2Jp4pVS zGV{YMQkEjiob^=J5djs>nOg;G1Shju+1l*(>`mEcb0TuebLQr3&$%p27LFG_CfqOl zLnIejMC(MS#9`tQ;<@6T;vXcL5`$!=b+n(R`Pio!gwdG52C# zTAnFyUEaC;#C(1J>ijbW{DR2^&lH>)nlMy9bj{E&h9wO%4qHF$f;K}tMf-yGGJL(k zUbwaJx=y3JPq({>Tr|9BLD8Y&u;S6hD~dlaNi1nB*;I06xP17%!*`cbOGlPIR(i55 zuFO!jq3p^C<%s)6>>J4%Su=9Q$S=w>%kAYmD@YY1Di&9qzANP}>s{L`vC6W_#g(5` zrBzL>dSeuARMn`JqrR*bSI?;4U&E=HRI{<>r`p2WMYX3!r;lzMy|*r;Zerbry6a<# z#&nN4GgdhEzOf&Siy3Dgw_`kgeBJo<ZcOSSX<{ryE zZ%zuCq@VQaWa{KGlQ&NOO<$>BqrX;PR{v!E6@$+3gy9?GFyj*ASEhVZx9LJdenWS| z#m4-`#f@Jz4Q*Q5bjhqUuP}cmoEJ6VZ+0J|C{)4%l_8$NW&wC7AY1z{V45G>!T+g8~WJu-R$n^-RBlpEZ(++ zzhuFZA0MCe_<^OerK_F@e4_1%Gt0`C?O2|?{L$sVt!P?td}ZOvElG1pD{o4@#^8Lx2;KCvve(OZTs3U*VV1t|E%iS4eMjpFI@lobJpk1 zJYW6%z75I^8#cynT(pU_scq9&FHC&l@QXz+?%15YdG(fvEel`5UTS;k>z60LeBzan zuk3wQ_3Gx=QeJy7|u-W~bw`|p*!_s)Lp{S0ET4S;Y5S))PR%||J-y(w(9f2B9{c&4|H=5D zEoT&G-aK1$_TU#aUz|E;IQPvz9sm68eAkyjUoO4CyRhM+tWqjz8Zb?xgTXe?!8uZ?em{ne!6je!Ozh@ zKmUvBm;Jwv`Srq$j^F6NE&Dy=_nm)?{Nr>_OHU8+TZ2oi2GC-_^}8Rfpj~Tlw4UI* z@5%0;BPuKk!+SpNIfI3cC@Cw!a1sVPNAQcJ=Ua?Le7J6st^zDBW5EQ68E1nByyq0w zg|Qe6MgW5q5Wr$H1DWjb5Ed&WJc`2!=WwFfEaGxMT#R>$2QisJ!9k(H!J*vX;9xFF zg1N3N>_6k6XE(-XK$G}nJP{+YaWWh4`3!ahNIm=Tp-@XIELGrw3Zsh*jiXR$bVfiR z6E?^ODshZN?p20jI0Yw@C?qPK#-Nf}Qc$wVl!P!bRXa-0Nt`-ILgPNR`sKo;qPX+|`n_CF|zB z_V~V!{`upxTi-o?{#so_`~0Qrx4n1b%b%3P$24|4@WgZ5_n*9QosE%5P+JO7CpwKP zC#sMj4x>N~rY3Tzk~xoYQ4RJ~AGsn;u0Ly^+pVh!H#lV9r_fLZ=&AC(N1+mHBaOwQ z6;9I^eO0)94bu9n(DNzAA`@k@v7y+t+U~NHjO6aJ%AUg>^e05TB@p0_hLk`$1k++h z%!bv&77-s7wM{@f;dT&IE0}QxvEXAmtOk=Ihpu1AiKqlTr=kMO1cHIl@i5{WmuQz0 z!((90i%c=B9v{+2Pr=jOHW1LbnAk=_yIgi$LeOZGJo%ClO^{69iSGA4UGGq|hAR#bVO>nU-4R+XDAo|{;&An}B zrDGWLx1Qg7bM`$c#I7~O5L_g}8unljjeJ|-tCBqskN_dE-%qCOcn@ z{8-wosBS1G=~y}Juup@*W5@Vt--pm!9d^)BEc$77f}dtKA|7s{9tKOj1@Wj8klt)< z=ydA|zS-Jr^W-g#)`kJR!Gin`z|GOrg32g`o7hn|v^ktWqYDkqeheAtQ?Kabq98>T z2!L9e?6vR#Eu*ciUVE%+*X3O)ZxHop=(M930Lpv2iw_Du=0bfgVKkTUI+s9wE^3_% z^*~Vm%cx5T6mN&RWKh(}DF1&q>Tf1=vL|r;4>co2HzZ~@} zqw$_UhdRuzclLL-=g$6MT-|96u(Nmc=dZz8^cEwL$y6FGAdnRl!e)nYIAQG2kYE-w z0M>mJvjZ@qW^qNU4MJh6D;Y-iJi z3avaVA%+ti!ih=DQtC!cw$A+9@^zbDdg;aIRxO_2-Z*YVzBn~5A~Y1Ti}OcLu-x~^ zQ!i|Pd*6F|cfGvs@p;brnj%G3LUb5Aik~6Z)fn3!T=~Kq?;kn&@$o}@Ut8Bb%QAjs zo-la`H!M0aTU|PK%FM;^uZnL7EN!cEs|%%M{;9R#07Uvc0RP~wF9TV{_)ovKY#bd(YH4)o@uTt zR%G#``t@56oc`w8jo*K{at`!MW=JVYB%@Q4il%wasl3SnRb-H`M`=zJNF+saq`$d_P(;_(fgXm zjmXVOis6KW$0m#NMvQNs@$kxx+unL--=3W>tzFV(udmk0GkH;AK~O-ZLRU4(I%DCo zH5)f?d2#(y-Cb=BV@KqQQexp(VQ55LicnKhJJ~vY-XlwvFMpzY!7NAPxQd~&41RQ2 z5QI+@KV6(Vyyl)J`}EoOcg?-8-D((Hu2l+>AUl)J4B^HkWJq$0E5}Z1Xtr8g%!Uay zBeaU_l=w(C1R#SI3IUcOR%=TuM~@vpVSL@F@}fK$s8M(^sB|I%`Dr;a4T|5g(qe6% zQkYt{$cB%i!heaBQejqVLTnTYZ#oPhFbE3eM#b`zQZq6If~?H+ zl!UnG@UUQJ02+WKWWWkxb0cG7dHlqL1b+OG=m<_I3{V;s)M$j#1DMDnJTfXeDk?I9 z8wOe!;1u|e{a^4F{Ljw>|Nmgv%Rj#^s@H8DCRw4<*j`oXZ<*(&Y^{>+%Mhc6o!%yS%|B zUfy6cFK@7^mp9nl%NuO+<44gIiC)yuoH*-e6NOw8Hls%o}VH z<_$Ir^9GxSd4tWvyul`7-e5B^1g-C>m^av54CBK0WDG;k_iWrlit{}kgMsh)_ - -// A basic smoke effect using a particle system -// Each particle is rendered as an alpha masked image - - -ParticleSystem ps; -Random generator; - -void setup() { - size(383,200); - generator = new Random(); - ps = new ParticleSystem(0,new PVector(width/2,height-25),null); - smooth(); -} - -void draw() { - background(0); - - // Calculate a "wind" force based on mouse horizontal position - float dx = map(mouseX,0,width,-0.2,0.2); - PVector wind = new PVector(dx,0); - ps.applyForce(wind); - ps.run(); - for (int i = 0; i < 2; i++) { - ps.addParticle(); - } - - // Draw an arrow representing the wind force - drawVector(wind, new PVector(width/2,50,0),500); - -} - -// Renders a vector object 'v' as an arrow and a location 'loc' -void drawVector(PVector v, PVector loc, float scayl) { - pushMatrix(); - float arrowsize = 4; - // Translate to location to render vector - translate(loc.x,loc.y); - stroke(255); - // Call vector heading function to get direction (note that pointing up is a heading of 0) and rotate - rotate(v.heading2D()); - // Calculate length of vector & scale it to be bigger or smaller if necessary - float len = v.mag()*scayl; - // Draw three lines to make an arrow (draw pointing up since we've rotate to the proper direction) - line(0,0,len,0); - line(len,0,len-arrowsize,+arrowsize/2); - line(len,0,len-arrowsize,-arrowsize/2); - popMatrix(); -} - -// Simple Particle System -// Daniel Shiffman - -// A simple Particle class, renders the particle as an image - -// Created 2 May 2005 - -class Particle { - PVector loc; - PVector vel; - PVector acc; - float lifespan; - PImage img; - - Particle(PVector l,PImage img_) { - acc = new PVector(0,0); - float vx = (float) generator.nextGaussian()*0.3; - float vy = (float) generator.nextGaussian()*0.3 - 1.0; - vel = new PVector(vx,vy); - loc = l.get(); - lifespan = 100.0; - img = img_; - } - - void run() { - update(); - render(); - } - - // Method to apply a force vector to the Particle object - // Note we are ignoring "mass" here - void applyForce(PVector f) { - acc.add(f); - } - - // Method to update location - void update() { - vel.add(acc); - loc.add(vel); - lifespan -= 2.5; - acc.mult(0); // clear Acceleration - } - - // Method to display - void render() { - //imageMode(CENTER); - //tint(255,lifespan); - //image(img,loc.x,loc.y); - // Drawing a circle instead - fill(255,lifespan); - noStroke(); - ellipse(loc.x,loc.y,img.width,img.height); - } - - // Is the particle still useful? - boolean dead() { - if (lifespan <= 0.0) { - return true; - } else { - return false; - } - } -} - -// Smoke Particle Syste -// Daniel Shiffman - -// A class to describe a group of Particles -// An ArrayList is used to manage the list of Particles - -class ParticleSystem { - - ArrayList particles; // An arraylist for all the particles - PVector origin; // An origin point for where particles are birthed - PImage img; - - ParticleSystem(int num, PVector v, PImage img_) { - particles = new ArrayList(); // Initialize the arraylist - origin = v.get(); // Store the origin point - img = img_; - for (int i = 0; i < num; i++) { - particles.add(new Particle(origin, img)); // Add "num" amount of particles to the arraylist - } - } - - void run() { - Iterator it = particles.iterator(); - while (it.hasNext()) { - Particle p = it.next(); - p.run(); - if (p.dead()) { - it.remove(); - } - } - } - - // Method to add a force vector to all particles currently in the system - void applyForce(PVector dir) { - // Enhanced loop!!! - for (Particle p: particles) { - p.applyForce(dir); - } - - } - - void addParticle() { - particles.add(new Particle(origin,img)); - } - - void addParticle(Particle p) { - particles.add(p); - } - - // A method to test if the particle system still has particles - boolean dead() { - if (particles.isEmpty()) { - return true; - } else { - return false; - } - } - -} - - - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/web-export/processing.js b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/web-export/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/web-export/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/web-export/texture.psd b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_08_ParticleSystemSmoke_b/web-export/texture.psd deleted file mode 100644 index 8208feb020b9552dba21c52ff59db597e4172699..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26456 zcmeHP33yY*+CC?Hn{-K&uCz_MZ)vlyT_8 zMMV}-K*5bgL+Yna|_P#Y7676j&XYC2n5TTD(p zzq7?+b!a;C6ZJ-0y-5Q!5(^Xggo(2`KT(Sm{IL~Pe4Wj1;>&U*Ig)IHNFn9Rr8!c$ zL?Mw0_!5ywB@`)zQc<>8r4h+BGBMwMB^Cq%m1j3LXsU}!+yw%cpV;JdwrYgJj*gC; z4rz|f-Y68S)oP(gB9ut7!6Mr+&Fa*5W?LOeE+@TyicAiJ-Q4Ol+pK)#S6^>ybLJ-| zqJsJ^cgtE@`wFr;a)?&u7;G)VPJOFToFfwUd4`O6fQm+EH|d==d#%l8DR8yDs>$ZG zIht&(d|i!VR*Tu7M_n##w;J6Y+1lGP zdBT3vzq;1Y%M}%U6~AQ=wX_It6?_h7aXZANJI-&J(@{IE)g-JoIc#lqgQ>V3aOe+q zcSu%LXv(Y(r`~EXl@%30b#lyRqei4vK~O1WBBey6P>ID_rC6>5iBzf3sYR+nBC-Z% z9T*d!E3z5d5cF=hM&wrd=iGW^y~%B*-3%`yy~V=@)%yS9{uVB7DyG!zfPp%#HyT|d zpNPpC)6{{|-e9$ui5P9w+Z`r^e12jt^q%hlmnW2m=s}I%fa0#efZhxyW1et;w7**3 z+03`-v_a8z`S!?qd;c9xCabSEi^~;Zb$cfcTZ6MhZ#QWhAr1z6;ki5x%;N3Z^|r8> z{|z1B(6`?q{DY2}JAvQpmHeN9zdvdXO?qpi$ygxl4cK16pX)JKKMov8z3&vSk@uHP z5KePL|GHqn`x0qxp0ANq1Fs4QU1Dk|5a$VRlJz$?kI;=pL*CLx3~6|G!X*@=)ScB+ z?VWX;@2s9`@2vefM_bL#0*SjcFR^#7yP#R^rXq8r$pLxf3V}qfgj)r-S^!HgfkY{T z8)Pb(KrR)*Ee0CoDycxCRtTgbu|O(T!L1g^C2&h6AOk;25!_&_M7$jIa7$%UNv>KU zFA^6@bR}AaOj@MWDV35!QK3j7QcKkmty=A__<)+ZtNoY7fvMAcn>aw4o8tgUHC5(L zlVxm?874FbdRPg?C1s&0@3HzyjQa0*~ zXr%Mfi<*3 z08uM|NEavsN`XqC763G2u|O;lh@}FtOaM^~Mq;G^LS6#4Fc4rIzz~tcXn|mdaRK3; zTcl7F%8O)TxmK!Gi{(WMh;N-p27^Q{Etbo)?#>+0V}Esw_pM!Ty+G_!-yH3IDh&~B z6*i-(K$<7KmDnQ&`_*MSU6tL|V78bF9M!`M`DMjAg;=dnWJ_`&jBjb@v+=HB4?phU zm!+`pr{zuaf8X-xuO#{#_*Z)M^5rkY3lQI|A1>eccxnA`c>&^^^~2>GA1|#RE-yfQ zvwpaIn4# zhs!rUURpm~UV!*!{c!ol$4l#n%L@?StRF7l_;_jkaCrgZoAtxx8y_#NA1*IIe6xPI zeBxauX zK3-ZsTwZ|qX8mya#>Y$Rhsz5P->e@l-}rcG{cw2!;+yruscJqseNRMrbJEgeD%+AgmU%V|vVrIj~lE+A$N*25g$!$9IG!c<<>U zC=4^=E+2A&XG03-)Nj(p5n6O|-DMrr$9EF7j_%{*iMn1T_y8h>#8pO`>tuT%DuK9g z!uA?Lmtw+(2GCd_rMa|j$?D}R`Xmz2;MjObdu>p?aV)!ELiqd{cnlDLmfY$hUqtF# zX?l9@L`PtOTw@psBM}^l;9RwJVJ9LaWE^)RkLr%vgHWLoc^HHQp#?J1FxTxy9`!PY z_4h;!V#zv4++`phB$#5Z7pt|j|{3Cn|k$# zr#awMxXDpxDR%&e4=9I9=s+9>H=SV0iadPN8|}8X)&U}#jX1e%vbMEA9#(M;^6ol{ z41AEj&1oBMvYPDZ7%&JhbcEP#9OyDe5~L|>Y2?G>-`##P9HXx-9$O1Vxxq!?50q3m z8chQvG`+=Ht8W}23pSV_pQ+PX<|wVLD6faFA0UT}Uhx3qfF_%Ly4GTDw7MG~;%a

{%+vUG-c%K5YV0YQ92B<)!1?4`Se2&{sAxsA<*>(M{7k*3F;#Zj#}~2nJbqkA_bU#I^pWQW7(xu ze7=Y7&yZ|Gs~u3rtH4-lgfC+N-37Fz!`X`DsMg&2W<-xPrvO#_Qd5V;QJ?n9lApn_kS+|{_Mu06B2c_|d?v+gGUOmY`>sI^`Ydlx zc$Ale%IiA|$S-mYVLpm#1Dthjv-4r4VKDKty@U8)&gfAsk9r8IO${crqA~I7Aj-_v zM(A#<(M){t#cUmLV$s9HznIO#10r2<4FqT19~gI14i@?$7bAar5TkII7uCv7XJ$W0soamCb39dQXDCjBqXUw zTGB{TE$MDjBWWsWI;o5F2x%E<4e15aHqsu_2c+YqGo)`w*T@)|Nsb^Vkh94uvW{Fy z9#3u{+sQM@3&=~!Ysj0)JIVXW$H-^Mm&m_RXcP{GPsyg_Qc5YKDF(_^%1p|`logcc zDcdOfD90#gDOV_eP=lzk)GVroT1Fj9ZKQTk=Tnzb*HgDr-=!X>o~QmqqtPO0X*4CR zls1kwg?2CPVcJu)EwtUVBeZk0Yjiq2nw~|^r&rSTbSHg2eL4LF`rGuQ^z-ze8B7L` zAz_p-#xtypxs0WZjf}S#M;R9wHv&QfQUWvql>x?pX#tA@)&=Yg_%Psnz>Pq5U|L{) zU~S-(z&U}-0yhV~8+bbKDwD}fWU85?m}cf|<}&6>%=ejRnZK~YSeYyxYa*+S^$6=Z z)^64(tgAsmL8(E*g2o3qgB}Um5cE#a=RrRQbAoe%%Yu!;vw~L!Zwo#ed^sc_Bqc-} za!<(gkfkB7hI|-uDKsE7HB=X>51kphGW7M(lcCqx9JZKU$!=jk%-+a8z`htp4@(Uz z4l{;zg{=*HC+r-D%t_+tI0nxBoOPUcIp?`FZW_0YJB7QD`y%%c_eywJxGcObyfb`d z_?zKpBFGV`5oHmUh(!^vM4X8DH8L(z8)=GsC~|Y;(a7sjL!yR7nW7d%ZHYP_^=mXg zx;VNy`myNk(VxXoVlrb!#dO3x9rJF?r6JrQxkC&?77Tf1$fvQS*v#1K*n4Bw#vY8l z78f5kJgzlvdE7g3m*OMhhs95cUlRXT{8u~#fX{lpUA4uJvdND03tt@SN+NQMA=|Sm3)2F7dN&hH=mZ8dM&Uh;0a3(2Jp4pVS zGV{YMQkEjiob^=J5djs>nOg;G1Shju+1l*(>`mEcb0TuebLQr3&$%p27LFG_CfqOl zLnIejMC(MS#9`tQ;<@6T;vXcL5`$!=b+n(R`Pio!gwdG52C# zTAnFyUEaC;#C(1J>ijbW{DR2^&lH>)nlMy9bj{E&h9wO%4qHF$f;K}tMf-yGGJL(k zUbwaJx=y3JPq({>Tr|9BLD8Y&u;S6hD~dlaNi1nB*;I06xP17%!*`cbOGlPIR(i55 zuFO!jq3p^C<%s)6>>J4%Su=9Q$S=w>%kAYmD@YY1Di&9qzANP}>s{L`vC6W_#g(5` zrBzL>dSeuARMn`JqrR*bSI?;4U&E=HRI{<>r`p2WMYX3!r;lzMy|*r;Zerbry6a<# z#&nN4GgdhEzOf&Siy3Dgw_`kgeBJo<ZcOSSX<{ryE zZ%zuCq@VQaWa{KGlQ&NOO<$>BqrX;PR{v!E6@$+3gy9?GFyj*ASEhVZx9LJdenWS| z#m4-`#f@Jz4Q*Q5bjhqUuP}cmoEJ6VZ+0J|C{)4%l_8$NW&wC7AY1z{V45G>!T+g8~WJu-R$n^-RBlpEZ(++ zzhuFZA0MCe_<^OerK_F@e4_1%Gt0`C?O2|?{L$sVt!P?td}ZOvElG1pD{o4@#^8Lx2;KCvve(OZTs3U*VV1t|E%iS4eMjpFI@lobJpk1 zJYW6%z75I^8#cynT(pU_scq9&FHC&l@QXz+?%15YdG(fvEel`5UTS;k>z60LeBzan zuk3wQ_3Gx=QeJy7|u-W~bw`|p*!_s)Lp{S0ET4S;Y5S))PR%||J-y(w(9f2B9{c&4|H=5D zEoT&G-aK1$_TU#aUz|E;IQPvz9sm68eAkyjUoO4CyRhM+tWqjz8Zb?xgTXe?!8uZ?em{ne!6je!Ozh@ zKmUvBm;Jwv`Srq$j^F6NE&Dy=_nm)?{Nr>_OHU8+TZ2oi2GC-_^}8Rfpj~Tlw4UI* z@5%0;BPuKk!+SpNIfI3cC@Cw!a1sVPNAQcJ=Ua?Le7J6st^zDBW5EQ68E1nByyq0w zg|Qe6MgW5q5Wr$H1DWjb5Ed&WJc`2!=WwFfEaGxMT#R>$2QisJ!9k(H!J*vX;9xFF zg1N3N>_6k6XE(-XK$G}nJP{+YaWWh4`3!ahNIm=Tp-@XIELGrw3Zsh*jiXR$bVfiR z6E?^ODshZN?p20jI0Yw@C?qPK#-Nf}Qc$wVl!P!bRXa-0Nt`-ILgPNR`sKo;qPX+|`n_CF|zB z_V~V!{`upxTi-o?{#so_`~0Qrx4n1b%b%3P$24|4@WgZ5_n*9QosE%5P+JO7CpwKP zC#sMj4x>N~rY3Tzk~xoYQ4RJ~AGsn;u0Ly^+pVh!H#lV9r_fLZ=&AC(N1+mHBaOwQ z6;9I^eO0)94bu9n(DNzAA`@k@v7y+t+U~NHjO6aJ%AUg>^e05TB@p0_hLk`$1k++h z%!bv&77-s7wM{@f;dT&IE0}QxvEXAmtOk=Ihpu1AiKqlTr=kMO1cHIl@i5{WmuQz0 z!((90i%c=B9v{+2Pr=jOHW1LbnAk=_yIgi$LeOZGJo%ClO^{69iSGA4UGGq|hAR#bVO>nU-4R+XDAo|{;&An}B zrDGWLx1Qg7bM`$c#I7~O5L_g}8unljjeJ|-tCBqskN_dE-%qCOcn@ z{8-wosBS1G=~y}Juup@*W5@Vt--pm!9d^)BEc$77f}dtKA|7s{9tKOj1@Wj8klt)< z=ydA|zS-Jr^W-g#)`kJR!Gin`z|GOrg32g`o7hn|v^ktWqYDkqeheAtQ?Kabq98>T z2!L9e?6vR#Eu*ciUVE%+*X3O)ZxHop=(M930Lpv2iw_Du=0bfgVKkTUI+s9wE^3_% z^*~Vm%cx5T6mN&RWKh(}DF1&q>Tf1=vL|r;4>co2HzZ~@} zqw$_UhdRuzclLL-=g$6MT-|96u(Nmc=dZz8^cEwL$y6FGAdnRl!e)nYIAQG2kYE-w z0M>mJvjZ@qW^qNU4MJh6D;Y-iJi z3avaVA%+ti!ih=DQtC!cw$A+9@^zbDdg;aIRxO_2-Z*YVzBn~5A~Y1Ti}OcLu-x~^ zQ!i|Pd*6F|cfGvs@p;brnj%G3LUb5Aik~6Z)fn3!T=~Kq?;kn&@$o}@Ut8Bb%QAjs zo-la`H!M0aTU|PK%FM;^uZnL7EN!cEs|%%M{;9R#07Uvc0RP~wF9TV{_)ovKY#bd(YH4)o@uTt zR%G#``t@56oc`w8jo*K{at`!MW=JVYB%@Q4il%wasl3SnRb-H`M`=zJNF+saq`$d_P(;_(fgXm zjmXVOis6KW$0m#NMvQNs@$kxx+unL--=3W>tzFV(udmk0GkH;AK~O-ZLRU4(I%DCo zH5)f?d2#(y-Cb=BV@KqQQexp(VQ55LicnKhJJ~vY-XlwvFMpzY!7NAPxQd~&41RQ2 z5QI+@KV6(Vyyl)J`}EoOcg?-8-D((Hu2l+>AUl)J4B^HkWJq$0E5}Z1Xtr8g%!Uay zBeaU_l=w(C1R#SI3IUcOR%=TuM~@vpVSL@F@}fK$s8M(^sB|I%`Dr;a4T|5g(qe6% zQkYt{$cB%i!heaBQejqVLTnTYZ#oPhFbE3eM#b`zQZq6If~?H+ zl!UnG@UUQJ02+WKWWWkxb0cG7dHlqL1b+OG=m<_I3{V;s)M$j#1DMDnJTfXeDk?I9 z8wOe!;1u|e{a^4F{Ljw>|Nmgv%Rj#^s@H8DCRw4<*j`oXZ<*(&Y^{>+%Mhc6o!%yS%|B zUfy6cFK@7^mp9nl%NuO+<44gIiC)yuoH*-e6NOw8Hls%o}VH z<_$Ir^9GxSd4tWvyul`7-e5B^1g-C>m^av54CBK0WDG;k_iWrlit{}kgMsh)_ - -// A simple Particle class - -class Particle { - PVector loc; - PVector vel; - PVector acc; - float lifespan; - - // Another constructor (the one we are using here) - Particle(PVector l) { - // Boring example with constant acceleration - acc = new PVector(0,0.05,0); - vel = new PVector(random(-1,1),random(-1,0),0); - vel.mult(2); - loc = l.get(); - lifespan = 255; - } - - void run() { - update(); - render(); - } - - // Method to update location - void update() { - vel.add(acc); - loc.add(vel); - lifespan -= 2.0; - } - - // Method to display - void render() { - imageMode(CENTER); - tint(lifespan); - image(img,loc.x,loc.y); - } - - // Is the particle still useful? - boolean dead() { - if (lifespan <= 0.0) { - return true; - } else { - return false; - } - } -} - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_09_AdditiveBlending/ParticleSystem.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_09_AdditiveBlending/ParticleSystem.pde deleted file mode 100644 index 1512cf487..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_09_AdditiveBlending/ParticleSystem.pde +++ /dev/null @@ -1,53 +0,0 @@ -// Smoke Particle Syste -// Daniel Shiffman - -// A class to describe a group of Particles -// An ArrayList is used to manage the list of Particles - -class ParticleSystem { - - ArrayList particles; // An arraylist for all the particles - PVector origin; // An origin point for where particles are birthed - - PImage tex; - - ParticleSystem(int num, PVector v) { - particles = new ArrayList(); // Initialize the arraylist - origin = v.get(); // Store the origin point - for (int i = 0; i < num; i++) { - particles.add(new Particle(origin)); // Add "num" amount of particles to the arraylist - } - } - - void run() { - Iterator it = particles.iterator(); - while (it.hasNext()) { - Particle p = it.next(); - p.run(); - if (p.dead()) { - it.remove(); - } - } - } - - void addParticle() { - particles.add(new Particle(origin)); - } - - void addParticle(Particle p) { - particles.add(p); - } - - // A method to test if the particle system still has particles - boolean dead() { - if (particles.isEmpty()) { - return true; - } else { - return false; - } - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_09_AdditiveBlending/_4_09_AdditiveBlending.pde b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_09_AdditiveBlending/_4_09_AdditiveBlending.pde deleted file mode 100644 index 00738c10d..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_09_AdditiveBlending/_4_09_AdditiveBlending.pde +++ /dev/null @@ -1,34 +0,0 @@ -// Smoke Particle System -// Daniel Shiffman - -// A basic smoke effect using a particle system -// Each particle is rendered as an alpha masked image - -ParticleSystem ps; - - -PImage img; - -void setup() { - size(800, 200, P2D); - - // Create an alpha masked image to be applied as the particle's texture - img = loadImage("texture.png"); - - ps = new ParticleSystem(0, new PVector(width/2, 50)); - smooth(); - -} - -void draw() { - - blendMode(ADD); - - background(0); - - ps.run(); - for (int i = 0; i < 10; i++) { - ps.addParticle(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp4_systems/NOC_4_09_AdditiveBlending/data/texture.psd b/java/examples/Books/Nature of Code/chp4_systems/NOC_4_09_AdditiveBlending/data/texture.psd deleted file mode 100644 index d532f15aa97ddc346e880e6801cfa46ec60e78f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26028 zcmeHP33yY*x4$<@(=FW>T4+hSZ)w(M?cTJdr7bOOX#o*PliN0Jnv^8n00pstfXbrm z$R;W%f`5=z1Vj*2{_Ns{B8UhmBK{FjLHo|!bh$0d^@;C$?|olxzdQHLIcLtC`OTR- zlj%2CnN?DT;h6nm!GlNME*R6!Dx0Xx$}eI?kvVTWuO}sCktmND@IK(b{IRX;o+#F z?yIw94UOFunXCe`l>(i)LD;Ho6p95RVYg){m;$J%H5Ni^Gh52dW@DPY?IpElo7q}x zZscjol6Xa0oxz0iDZ;+$J@xlkBC@qMB26L^ixWlSM2WIoELO|JYOy2{P!fqKM(mn> zY!pFn=(RTOU$N3lx33+u-ca54m#p+?cG^f0B9JMdlRb*?>cgk&485+qFB+RHMzYKG zIw4^s8VHlk3jHDO-5+|Ly4q}M(Av_pjg3ZwPK&x+*lf~wc4T8$&!h-@RR3wOp_hw_ zx*fl75H&Oi?-zVlTTU~?WoMk|7QMMvZ`0}egG-WifbMe2N$)uuJ+ zi2Up{a7SP;=+z>r5`s#RBvMF3a-~?DsSwLFz>zBC8kIYjr5@(sby}K0xgcyD3uZ!A7j+YFmreLS)uJ9MHY+>=t_$>1*2lwlErccYvMSyI;B@v`;_&W3L;V zp}J?5={5S0|wlqm+ZGG5%OAUc$H51u}8o~-?WOBYlrhr=sw~7xFIbWhkf*W|s zB)&{4f?EtU@Rd@&L?!1-MPj~Gtb|*|mr3B3N`MD;6e74mSAp^}ki#ual1h>@C6b)1 zT!ls<%gu#+PHt|dOq`voQAu)=a&k5BmLgH?v_ zTtueOOA4{Xo=QlLJ(U7qCbsJ&@lh!SnL>|3Zvh8V;3O$!A~J>E1RDAhQs{k!6k-FV zpbx1ErAp9*6xAh#NI@y8MG6swQYZ^4Sr+0aNt^^yl!CXA+Bpi6R-#k|enLv>sANDZ zB#5toSc4QIGD)lgn(ihX-%aq{dHW-OCYw4gYUVe^7E>_9qi4p;X@qP6k+Iai0ho1`Y zJ4M+2L#6j@(mm7u!$eO5|6#*abB;==XwcFQxM(4wDmdVxqCrbL;G%_ys^EZ&iUuw1 zfQuF)s)7S9DjKx311?&Ks0t3asA$mA4!CF`qAEDxqM|`dJK&;)h^pX#i;4y5Ww6p^*T8O9$4!Edj(9#aLXd$91IN+k9K}$Q}qJ@a6;DC#Y1}*J?ixwiPf&(rp z8nmYO;Jj}O9PC9WgPA{)CxyMSJb2>p*ZCw*4M&qQPckKw^vM`Tmbyk}JvikS zt;q_<;|Ppv7eK6Lp6{WPU_wy={!tW zT@4Z=q-?vile22^l5UO!Bsew_(k>n3H;yIta7dfKLLLJIpe6Uan3s|Gev*!kN0E_O zAk!Gez!+qXLFVk<+OZRn943x;B9DAW?Lnxp$TBV@2cZQ#Muz?FL>~1r=%Iwv?T;vC zJ|vxWpghLwyxp*2(Em2f0JjlhK@UiYLDtm+Kz3hL9uK(a?sZWWx&)n0qO7UOXoLr9 zFdI&LoAlP=syZFyI?I*nY^Z9|^>R3=Z8V!|AWvR}M752Y&$5{tI`cfFP+C*lB}aL- z6;2ux)(T^x6>@m5dYniZuzlfnCNufj6x+@<7IRZ$FBaQOo`xk%O$|_nlT(JQ+mE+G z-b34DGY=w6gasWf1qOzWrFJU2*_9CoN%9+Nc<}h2Za))_W|!v-FNdl+!A0Qr<`h|L zh+Z7F)@Uo&*7V|e>If)DwA%8mdF4fgRdAvn8FcAl_fmGPHCx7K8Vxn3&c=J$8=u$3 zhLX;DqFUQzv;pbbOjvC9QLpG?_f~hWsv%D|QNZ=F+s_)*Er24}5VHwk?P@bO7B|_f zL|0%SnVS&;=^iep%4~yxx`*!$-Co;Qog7uM$QZ_fn~{E7#430Lpj?C`}$`KyxhRr5d19AgVYu6uOE++aLl#7t@#<+sHoQ#p>dCa28O>%OhHhgw2*%0^iWk zTJ-RRi-tz63Fb3WAUF26C9>@z&@a1XDiWDn208s5(^ zvoYuN@TwML*tV${7W73AFLEV@d9`EM)}xg61fqDMe0sw`=mZGR?u%BTTl2vLr9J_w zulqzGFWWwZc_^xNaN@Pe!h`jOj^HKs4dTCDkm44_4}K|8O`vrR!K;8MGni_iyG?on z`4tg^sn@whiiN*fjA8+i_P7SZZ_S^W{}=)0ebgUg{&*N;`MG1vQOiMsclTSNYXycz zUM2UEJ??=9IhpoK7_%YEuo}o|0n?P0^K?y?X1fXtJ)AH%%nS3!g0X>E1QrYPvjkIM z$yf%KgAK-tVLdkj8x1SCTC4$9b1m3J>?v#-HVd1B&BvBtE3h@#I&1^B3EPJ4!rsF^ zz&^%~VV_`Uuyfc&><8>Rb_=@$D-CDd1NXy&aV{Q(C*TrXiKpQ?cp+YjkHE*`HMj|H z!YATS`nHbZZ8ORJ{CNh;w4YQazl3C5P zFrQ@3WG-N?W^Q2aWFBOmWS(PQW&Xxuv;0^*Rw65zmB$*!(y_*|o@71CTEbe(+REC` zI>|cEy3YF3$-^ncDZxqYl*` z>^k-Y_OtAl*c;h<*~i%z*f*V>or9edoKu~Powd$3=V{K1o!2|>aX#UE(fL;wcNeaU z#3k2dq>IUAipv6**IjnIoN&41a>v!%HOf`(TI{NKZF8ONy2f><>rvN>u6Nvg++y5P z-OAnS+@5k<fZLaDH{9Lb!`)TxL){JTlie4&zvX_&{k;2c9A8d6N5dJ#Y2rN3 zd5yD|^Eu~+hlfYBM~25p51YsH9_u{b_c-hEtEZo*z%$=d?>WhHspnSD6Q0++T)m>a zGQCE7jrUsMwb|>a*Hv#5yg&86>Eq`k_9^yh@Ojqfb)OG?F8ezB zM*HUY>V4aNU-o_9_kthOFTzjbr}KN-Z;jspzl;8C{}}&#|2qF!{%`sp@xLD68;}%G z5zrd2G~nHUbAimj=)n9yW8mz-O@XHafA1ICFS8%fZ$`fj{Z90|9W)>)BZvr^8MHCz zlc3*&dBHis^}%z4w*`OIpVdFU|Iq#|{g?MY(EsWH{{hJZbOUA%*fija5JpIRNNLD~ zke5RahujPu7&<7lF?4b0`=M6{1`f;^SU2#+fx8D@;remYxCZWv+&$dyc>%mko{_hR zx1V=CEF>&1tSM|&*paY1;W6RE!l#694F4*^EkYSl9r0qszKH9Q+{mKHiIHzaei7vw zrHrbLS{QXO>UMNYbY=AP=xx!LV}fGxW5&n45%XoNM{IiRxY*UPr{dUg%DDQtm*S4a zGva0Owed^ik0vk@&iNBivX(A^vGqE}Gjl}bUKtZ8kieQ`InlMs0 zQaD$5Q23`vCNhfFh|Y+8#e>CD#5=|Rk;F@MlBJSUQV(gabdq$t^yj36BqC{f(q}S1 zS&?kIY@h58xk7G{Z;)S6L@LHAmMK0}`YTJ6&nge8oK#t=Nvd6{-_&xoO}$C|Q*vT* zee&zcms4U=h?F%c7gEDhwW+I8&!zFw#-^=IJC`1ou1#N^{!KBnOpZ+-m3 z(fvmoN54D9Ym9cx=CMv=E62V*_O7;AyIOm*D!*!3)pealw@~+kK12Va{tA&w%p)#U zr&iCazFd=9^Fqy)+Vt85wO0)q!xF>Kb$N9w>TcH;*S}WZVXQQ6Y;b89+pxprYpOTx zHxD$onvXXoG)`+gH%>in{p z+@7j`>fcjDQ|3+i<>|_&ceaPNPj0_3bU~J=gJk_47w&%V#g2!=7WBb9!$2+_m$3=8d0s;f10X zw!X-FapsG^%pWuV!v#qTRxET|*tGE6qQXVn7e_9hv-s|k+9jVX&04x~S;(>(%Wl7< zf9b^XjO80vgszyi;`fz?m7lE|v})_>=+z5eX20D0@^@=0)*O6A`O3Oi`@cHt)jwV{ zy>@PG>DvA46zkT#9`gF^HyCd;y>VszsP)I*%zktGhQtl4HU@5-^%nM4(_7#FYwW*H zZz|ZdZ?kgqhPR{MUbe+=%gn9#*0!zJx7BVtw|&I+<2wfL*tauz=azQ_@4U7vY}e9v z1Kypz+iiFI?v6d<_uSmuxcBONHSb;6H)h|N_lLiKYX8vvM-CJmIP^j82k#%uJhY-g9sz2QEk@BN$AIm@9dRTUN%fDs+-f~2KWb0AI(e1}n$95i1IllWu`ib{WW}p1v zRQ{=tKN<4L@zcXjfA;C9PtSd(|LpST#?OELqWOzEXC{B?^ySR2yuVs-HstK;uj9Vn zcus!q-SgS!4}Vkk&6x|j3qO2o{r2v~_U}BtTX2bcY29VX%*^K{Mqtz$A6x^5q#sdUy^>=ceCW?*;@^_?%baFYw)jY ze^dT;@b}8!FWqUm>wI_7A8~)|{IlTCFFP7KI>_G|{^V)^Ee7nr{?Q8Bz6M9@30~(t zw)5wR5(~ocj?X&IVcvst^K&trfx-R}{37Z25#x{_LmQ(h0*z~!Cz-?alfeSsaRzJ0 zI4&+Ot}Yx`SB{Uno4Zed7l-2&5aj0<;O7_Q!y&KEhdt9b#Xa2JJv=?UJw3hsJv}}B zQR3-uFXHo840PAT zu5RwIP1ak8V+>}O&>O>9IFrF*I61RjoR}Ob2z{8WFki7#=1{F)__(JeZ2!5d{*@IG z8BqFOl{CpR<+#QnAu(7*=0X~(EwHyh_C2M| zU2W&YVwn5gjz79ec0XC<-ZjJ!Tnthhc485YY@6Uqg&h!(03qy0kQdlNCFpPGLTwvi z;fawQW0MK_hGNngD};UaHW)k>jEDApNV&;s0U67vZL^U1HiI7J;U@ji8LNyak2(R# z4W{bWPC1#cH`SY|d84(lx>sIjMD}~(X02^Nb>zWK?yKvXtTv$0g@$GihA!yyq3DB^ zz(o$Yf|rD)96qC^H#b#fo-EmQZCBJgq#xC-7W4u@Wgm3$K)}Q7s81o4rjS;rkf={V zt+S)<2ExCMx`agWL8wb;QD>s^|Ho0kku&w^-$0#ZkM#$j{z$PdeJJWuTGYw)%>QxJ z?_TzL>93&H&8Ck^USWoQJm<+r`!0!`m+)Xu!a*h^Xk8n3(9u z2wrIae*QjQ95)wdXIBm^ko)!LMnuQ)1+eH42@?}yqryUi1O2=`+@Z9mPe5>JSagC= zDpw_^q$I1AGKnBAiWd^(@9p6RV*lWQ5pjYfRa#a~-r&LcgL1M`lu|)#cqmfv@CI>Y zf<&2?Q&3V~Ida7Cin1YtHK__wTm(|^_6r&q$(JT;1`i!RT3=IFXQlp%fzp zKfivV5eZ2tIYTPP)R=6o6DEvru{IE+$_uj8qPXw@fdK=;;>5{0Lq_OLEt96reE#|8 zX0$(Hs~cNcn57U#bAyAp(E_Dr$Oxiw;`BKSm#tj6V%hxXo^CT$RTiYn_>rLl!sBIW zgDZ98o}9U0)!Gf4H*b3LwdF57Goe9So|i0+;SG!ysupmPuHA9y^!Y2-e){pdvnThz zy=LBI^O%w>c|x=(Ij^#&b=FH8_8vWZ<@&ALH?Lj%;-j6fFPv)CmFFlEW5lWXBMcLs zTe)ff$#1URx_kG|FF$;JbkByRGn$EExoSa-IA!pNI*@NZaO%QOx9 z8$W*g*+)CpE^N1GOS2XH$V6pMS(UXNerFsw`So`{T>bvrFOTipv}*1o)9B(%SvixsC1t{`mfFRb3U>%hlHj~)GJ z-}X0`&z{t%Ez4C4qe7z+m73zm>)WQ!U%h_IJA3x-*|}-m@_Fq|wIhl$WeMT^!{eo? zdF5kG6Q<8w_VT(nH>_W~dhzV`*1FL{bCN|dyndlk0!2naWtFLI%B;DImM&egV9qm> zo9f4u<)ukz9~2rM4PS;-r)RFs>84#S-Mq`Cn|Qf& zGcT8J>gCeSy - -// A simple Particle class - -class Particle { - - PVector location; - PVector velocity; - PVector acceleration; - float lifespan; - - Particle(PVector l) { - acceleration = new PVector(0,0.05); - velocity = new PVector(random(-1,1),random(-2,0)); - location = l.get(); - lifespan = 255.0; - } - - void run() { - update(); - push(); - display(); - pop(); - } - - // Method to update location - void update() { - velocity.add(acceleration); - location.add(velocity); - lifespan -= 2.0; - } - - - void push() { - pushMatrix(); - } - - void pop() { - popMatrix(); - } - - // Method to display - void display() { - stroke(0,lifespan); - fill(0,lifespan); - translate(location.x,location.y); - ellipse(0,0,8,8); - } - - // Is the particle still useful? - boolean isDead() { - if (lifespan < 0.0) { - return true; - } else { - return false; - } - } -} - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/ParticleSystemInheritance_pushpop/ParticleChild.pde b/java/examples/Books/Nature of Code/chp4_systems/ParticleSystemInheritance_pushpop/ParticleChild.pde deleted file mode 100644 index 4e2cc630f..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/ParticleSystemInheritance_pushpop/ParticleChild.pde +++ /dev/null @@ -1,20 +0,0 @@ -class ParticleChild extends Particle { - - // We could add variables for only Confetti here if we so - - ParticleChild(PVector l) { - super(l); - } - - // Inherits update() from parent - - // Override the display method - void display() { - super.display(); - float theta = map(location.x,0,width,0,TWO_PI*2); - rotate(theta); - stroke(0); - line(0,0,50,0); - } -} - diff --git a/java/examples/Books/Nature of Code/chp4_systems/ParticleSystemInheritance_pushpop/ParticleSystem.pde b/java/examples/Books/Nature of Code/chp4_systems/ParticleSystemInheritance_pushpop/ParticleSystem.pde deleted file mode 100644 index fdba58bf1..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/ParticleSystemInheritance_pushpop/ParticleSystem.pde +++ /dev/null @@ -1,34 +0,0 @@ - -class ParticleSystem { - ArrayList particles; - PVector origin; - - ParticleSystem(PVector location) { - origin = location.get(); - particles = new ArrayList(); - } - - void addParticle() { - float r = random(1); - if (r < 0.5) { - particles.add(new Particle(origin)); - } else { - particles.add(new ParticleChild(origin)); - } - } - - void run() { - Iterator it = particles.iterator(); - while (it.hasNext()) { - Particle p = it.next(); - p.run(); - if (p.isDead()) { - it.remove(); - } - } - } -} - - - - diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_1_simple/NOC_gl.pde b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_1_simple/NOC_gl.pde deleted file mode 100644 index d22e4bb0a..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_1_simple/NOC_gl.pde +++ /dev/null @@ -1,11 +0,0 @@ - - -void renderImage(PImage img, Vec3D _loc, float _diam, color _col, float _alpha ) { - pushMatrix(); - translate( _loc.x, _loc.y, _loc.z ); - tint(red(_col), green(_col), blue(_col), _alpha); - imageMode(CENTER); - image(img,0,0,_diam,_diam); - popMatrix(); -} - diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_1_simple/emitter.pde b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_1_simple/emitter.pde deleted file mode 100644 index 479138397..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_1_simple/emitter.pde +++ /dev/null @@ -1,89 +0,0 @@ - -/* -The emitter is just an object that follows the cursor and -can spawn new particle objects. It would be easier to just make -the location vector match the cursor position but I have opted -to use a velocity vector because later I will be allowing for -multiple emitters. -*/ - -class Emitter{ - Vec3D loc; - Vec3D vel; - Vec3D velToMouse; - - color myColor; - - ArrayList particles; - - Emitter( ){ - loc = new Vec3D(); - vel = new Vec3D(); - velToMouse = new Vec3D(); - - myColor = color( 1, 1, 1 ); - - particles = new ArrayList(); - } - - void exist(){ - setVelToMouse(); - findVelocity(); - setPosition(); - iterateListExist(); - render(); - - gl.glDisable( GL.GL_TEXTURE_2D ); - - if( ALLOWTRAILS ) - iterateListRenderTrails(); - } - - void setVelToMouse(){ - velToMouse.set( mouseX - loc.x, mouseY - loc.y, 0 ); - } - - void findVelocity(){ - vel.interpolateToSelf( velToMouse, .35 ); - } - - void setPosition(){ - loc.addSelf( vel ); - - if( ALLOWFLOOR ){ - if( loc.y > floorLevel ){ - loc.y = floorLevel; - vel.y = 0; - } - } - } - - void iterateListExist(){ - for( Iterator it = particles.iterator(); it.hasNext(); ){ - Particle p = (Particle) it.next(); - if( !p.ISDEAD ){ - p.exist(); - } else { - it.remove(); - } - } - } - - - void render(){ - renderImage( emitterImg, loc, 150, myColor, 1.0 ); - } - - void iterateListRenderTrails(){ - for( Iterator it = particles.iterator(); it.hasNext(); ){ - Particle p = (Particle) it.next(); - p.renderTrails(); - } - } - - void addParticles( int _amt ){ - for( int i=0; i<_amt; i++ ){ - particles.add( new Particle( loc, vel ) ); - } - } -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_1_simple/flight404_particles_1_simple.pde b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_1_simple/flight404_particles_1_simple.pde deleted file mode 100644 index d7018b981..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_1_simple/flight404_particles_1_simple.pde +++ /dev/null @@ -1,160 +0,0 @@ -// Updated version of flight404 Particle Emitter release 1 -// This works with Processing 1.0 -// All of the advanced openGL direct calls that use display lists, etc. have been stripped out -// It's my intention to redo this example using GlGraphics (http://glgraphics.sourceforge.net/) -// But for now, just want to make sure it works in principal - -// February 28 2011 -// Daniel Shiffman - -// Source Code release 1 -// Particle Emitter -// -// February 11th 2008 -// -// Built with Processing v.135 which you can download at http://www.processing.org/download -// -// Robert Hodgin -// flight404.com -// barbariangroup.com - -// features: -// Toxi's magnificent Vec3D library -// perlin noise flow fields -// ribbon trails -// OpenGL additive blending -// OpenGL display lists -// -// Uses the very useful Vec3D library by Karsten Schmidt (toxi) -// You can download it at http://code.google.com/p/toxiclibs/downloads/list -// -// Please post suggestions and improvements at the flight404 blog. When nicer/faster/better -// practices are suggested, I will incorporate them into the source and repost. I think that -// will be a reasonable system for now. -// -// Future additions will include: -// Rudimentary camera movement -// Magnetic repulsion -// More textures means more iron -// -// UPDATES -// -// February 11th 2008 -// Reorganized some of the OpenGL calls as per Simon Gelfius' suggestion. -// http://www.kinesis.be/ - - -import toxi.geom.*; -import processing.opengl.*; -import javax.media.opengl.*; - -PGraphicsOpenGL pgl; -GL gl; - - -Emitter emitter; -Vec3D gravity; -float floorLevel; - -PImage particleImg; -PImage emitterImg; - -int counter; - - -boolean ALLOWGRAVITY; // add gravity vector? -boolean ALLOWPERLIN; // add perlin noise flow field vector? -boolean ALLOWTRAILS; // render particle trails? -boolean ALLOWFLOOR; // add a floor? - // Turning on all of these options will make things - // slow down. - -void setup(){ - size( 600, 600, OPENGL ); - // Lately I have gotten into the habit of limiting the color range to be - // 0.0 to 1.0. It works this way in OpenGL so I might as well get used to it. - colorMode( RGB, 1.0 ); - - // Turn on 4X antialiasing - hint( ENABLE_OPENGL_4X_SMOOTH ); - - // More OpenGL necessity. - pgl = (PGraphicsOpenGL) g; - gl = pgl.gl; - - // Loads in a particle image from the data folder. Image size should be a power of 2. - particleImg = loadImage( "particle.png" ); - emitterImg = loadImage( "emitter.png" ); - - emitter = new Emitter(); - gravity = new Vec3D( 0, .35, 0 ); // gravity vector - floorLevel = 400; -} - -void draw(){ - background( 0.0 ); - perspective( PI/3.0, (float)width/(float)height, 1, 5000 ); - - // Turns on additive blending so we can draw a bunch of glowing images without - // needing to do any depth testing. - gl.glDepthMask(false); - gl.glEnable( GL.GL_BLEND ); - gl.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE); - - emitter.exist(); - - // If the mouse button is pressed, then add 10 new particles. - if( mousePressed ){ - if( ALLOWTRAILS && ALLOWFLOOR ){ - emitter.addParticles( 5 ); - } else { - emitter.addParticles( 10 ); - } - } - - counter ++; -} - - -void keyPressed(){ - if( key == 'g' || key == 'G' ) - ALLOWGRAVITY = !ALLOWGRAVITY; - - if( key == 'p' || key == 'P' ) - ALLOWPERLIN = !ALLOWPERLIN; - - if( key == 't' || key == 'T' ) - ALLOWTRAILS = !ALLOWTRAILS; - - if( key == 'f' || key == 'F' ) - ALLOWFLOOR = !ALLOWFLOOR; - -} - - -// This method should be nicer, but it isnt. I use getRads to get a perlin noise -// based angle in radians based on the x and y position of the object asking for it. -// Perlin noise is supposed to give you back a number between 0 and 1, but it wont -// necessarily give you numbers that range from 0 to 1. A usual result is more like -// .25 to .75. -// -// So the point of this method is to try to normalize the values to a -// range of 0 to 1. It's not perfect, and I still get weird results. -// For instance, the mult variable is supposed to be the multiplier for the range. -// So if i wanted a random angle between 0 and TWO_PI, I would set the mult = TWO_PI. -// But when I do that, I find the Perlin noise tends to give me a left-pointing angle. -// To counteract, I end up setting the mult to 10.0 in order to increase the chances -// that I get a nice range from at least 0 to TWO_PI. -float minNoise = 0.499; -float maxNoise = 0.501; -float getRads(float val1, float val2, float mult, float div){ - float rads = noise(val1/div, val2/div, counter/div); - - if (rads < minNoise) minNoise = rads; - if (rads > maxNoise) maxNoise = rads; - - rads -= minNoise; - rads *= 1.0/(maxNoise - minNoise); - - return rads * mult; -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_1_simple/particle.pde b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_1_simple/particle.pde deleted file mode 100644 index 16441c9c5..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_1_simple/particle.pde +++ /dev/null @@ -1,208 +0,0 @@ -/* -General Structure notes. - My classes tend to have a similar naming scheme and flow. I start with the 'exist' method. - Exist is what an object needs to do every frame. Usually 'existing' consists of four main things. - 1) Find the velocity. This involves determining what influences there are on the velocity. - 2) Apply the velocity to the location. - 3) Render the object. - 4) Age the object. - - I also use the metaphor of aging and death. When first made, a particle's age will be zero. - Every frame, the age will increment. If the age reaches the lifeSpan (which is a random number - that I set in the constructor), then the boolean ISDEAD is set to true and the arraylist iterator - removes the dead element from the list. - */ - - - -class Particle { - int len; // number of elements in position array - Vec3D[] loc; // array of position vectors - Vec3D startLoc; // just used to make sure every loc[] is initialized to the same position - Vec3D vel; // velocity vector - Vec3D perlin; // perlin noise vector - float radius; // particle's size - float age; // current age of particle - int lifeSpan; // max allowed age of particle - float agePer; // range from 1.0 (birth) to 0.0 (death) - float bounceAge; // amount to age particle when it bounces off floor - boolean ISDEAD; // if age == lifeSpan, make particle die - boolean ISBOUNCING; // if particle hits the floor... - - - Particle( Vec3D _loc, Vec3D _vel ) { - radius = random( 10, 40 ); - len = (int)( radius ); - loc = new Vec3D[ len ]; - - // This confusing-looking line does three things at once. - // First, you make a random vector. - // new Vec3D().randomVector() - // Next, you multiply that vector by a random number from 0.0 to 5.0. - // scaleSelf( 5.0 ); - // Finally, you add this new vector to the original sent vector. - // _loc.add( ); - // This is just a way to make sure all the particles made this frame - // don't all start on the exact same pixel. This staggering will be useful - // when we incorporate magnetic repulsion in a later tutorial. - startLoc = new Vec3D( _loc.add( new Vec3D().randomVector().scaleSelf( random( 5.0 ) ) ) ); - - for( int i=0; i floorLevel ) { - ISBOUNCING = true; - } - else { - ISBOUNCING = false; - } - } - - if( ISBOUNCING ) { - vel.scaleSelf( .75 ); - vel.y *= -.5; - } - } - - void setPosition() { - // Every frame, the current location will be passed on to - // the next element in the location array. Think 'cursor trail effect'. - for( int i=len-1; i>0; i-- ) { - loc[i].set( loc[i-1] ); - } - - // Set the initial location. - // loc[0] represents the current position of the particle. - loc[0].addSelf( vel ); - } - - void render() { - // As the particle ages, it will gain blue but will lose red and green. - color c = color( agePer, agePer*.75, 1.0 - agePer ); - renderImage(particleImg, loc[0], radius * agePer, c, 1.0 ); - } - - void renderTrails() { - float xp, yp, zp; - float xOff, yOff, zOff; - beginShape(QUAD_STRIP); - for ( int i=0; i lifeSpan ) { - ISDEAD = true; - } - else { - // When spawned, the agePer is 1.0. - // When death occurs, the agePer is 0.0. - agePer = 1.0 - age/(float)lifeSpan; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/NOC_gl.pde b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/NOC_gl.pde deleted file mode 100644 index 2f91c0f1b..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/NOC_gl.pde +++ /dev/null @@ -1,49 +0,0 @@ - -int squareList; -void initGL(){ - pgl.beginGL(); - squareList = gl.glGenLists(1); - gl.glNewList(squareList, GL.GL_COMPILE); - gl.glBegin(GL.GL_POLYGON); - gl.glTexCoord2f(0, 0); gl.glVertex2f(-.5, -.5); - gl.glTexCoord2f(1, 0); gl.glVertex2f( .5, -.5); - gl.glTexCoord2f(1, 1); gl.glVertex2f( .5, .5); - gl.glTexCoord2f(0, 1); gl.glVertex2f(-.5, .5); - gl.glEnd(); - gl.glEndList(); - pgl.endGL(); -} - -void renderImage( Vec3D _loc, float _diam, color _col, float _alpha ){ - gl.glPushMatrix(); - gl.glTranslatef( _loc.x, -_loc.y, _loc.z ); - pov.glReverseCamera(); - gl.glScalef( _diam, _diam, _diam ); - gl.glColor4f( red(_col), green(_col), blue(_col), _alpha ); - gl.glCallList( squareList ); - gl.glPopMatrix(); -} - -// This will allow you to draw images that are oriented to the floor plane. -void renderImageOnFloor( Vec3D _loc, float _diam, color _col, float _aa ){ - gl.glPushMatrix(); - gl.glTranslatef( _loc.x, -_loc.y, _loc.z ); - gl.glScalef( _diam, _diam, _diam ); - gl.glRotatef( 90, 1.0, 0.0, 0.0 ); - gl.glColor4f( red(_col), green(_col), blue(_col), _aa ); - gl.glCallList( squareList ); - gl.glPopMatrix(); -} - -// This will allow you to specify a rotation for images that are oriented perpendicular to the eyeNormal -// which is the vector pointing from the camera's eye to the camera's point of interest. -void renderImageAndRotate( Vec3D _loc, float _diam, color _col, float _aa, float _rot ){ - gl.glPushMatrix(); - gl.glTranslatef( _loc.x, -_loc.y, _loc.z ); - gl.glRotatef( degrees( _rot ), pov.eyeNormal.x, pov.eyeNormal.y, pov.eyeNormal.z ); - pov.glReverseCamera(); - gl.glScalef( _diam, _diam, _diam ); - gl.glColor4f( red(_col), green(_col), blue(_col), _aa ); - gl.glCallList( squareList ); - gl.glPopMatrix(); -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/cursor.pde b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/cursor.pde deleted file mode 100644 index ee2909cb9..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/cursor.pde +++ /dev/null @@ -1,25 +0,0 @@ -class Cursor{ - Vec3D loc; - Vec3D vel; - - Cursor(){ - loc = new Vec3D(); - vel = new Vec3D(); - } - - void exist(){ - // 2.35 is an arbitrary number. Ideally, this cursor would function - // properly regardless of the camera's rotation and distance from the object. - // Im not sure how to make that happen... 3D interaction with the cursor has - // been low on my research list. Think of this as a crappy placeholder. - loc.set( ( mouseX - xMid ) * 2.25, ( mouseY - yMid ) * 2.25, 0 ); - } - - void render(){ - pushMatrix(); - translate( loc.x, loc.y, loc.z ); - fill( 1, 0, 0 ); - sphere( 10 ); - popMatrix(); - } -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/emitter.pde b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/emitter.pde deleted file mode 100644 index 04eb2045a..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/emitter.pde +++ /dev/null @@ -1,182 +0,0 @@ -class Emitter{ - Vec3D loc; - Vec3D vel; - Vec3D velToMouse; - float radius; - - Texture coronaTex; - Texture emitterTex; - Texture particleTex; - Texture reflectionTex; - - color myColor; - - ArrayList particles; - ArrayList nebulae; - - Emitter( ){ - - try { - coronaTex = TextureIO.newTexture(new File(dataPath("corona.png")), true); - emitterTex = TextureIO.newTexture(new File(dataPath("emitter.png")), true); - particleTex = TextureIO.newTexture(new File(dataPath("particle.png")), true); - reflectionTex = TextureIO.newTexture(new File(dataPath("reflection.png")), true); - } - catch (IOException e) { - println("Texture file is missing"); - exit(); // or handle it some other way - } - - loc = new Vec3D(); - vel = new Vec3D(); - velToMouse = new Vec3D(); - - radius = 100; - - myColor = color( 1, 1, 1 ); - - particles = new ArrayList(); - nebulae = new ArrayList(); - } - - void exist(){ - findVelocity(); - setPosition(); - iterateListExist(); - render(); - - gl.glDisable( GL.GL_TEXTURE_2D ); - - if( ALLOWTRAILS ) - iterateListRenderTrails(); - } - - void findVelocity(){ - Vec3D dirToMouse = new Vec3D( mouse.loc.sub( loc ).scale( .15 ) ); - vel.set( dirToMouse ); - } - - void setPosition(){ - loc.addSelf( vel ); - - if( ALLOWFLOOR ){ - if( loc.y > floorLevel ){ - loc.y = floorLevel; - vel.y = 0; - } - } - } - - void iterateListExist(){ - gl.glEnable( GL.GL_TEXTURE_2D ); - - - int mylength = particles.size(); - for( int i=mylength-1; i>=0; i-- ){ - Particle p = ( Particle )particles.get(i); - if( p.ISSPLIT ) - addParticles( p ); - - if ( !p.ISDEAD ){ - // pgl.bindTexture( images.particle ); - particleTex.bind(); - particleTex.enable(); - p.exist(); - particleTex.disable(); - - } - else { - particles.set( i, particles.get( particles.size() - 1 ) ); - particles.remove( particles.size() - 1 ); - } - } - - if( ALLOWFLOOR ){ - // pgl.bindTexture( images.reflection ); - reflectionTex.bind(); - reflectionTex.enable(); - for( Iterator it = particles.iterator(); it.hasNext(); ){ - Particle p = (Particle) it.next(); - p.renderReflection(); - } - reflectionTex.disable(); - } - - // pgl.bindTexture( images.corona ); - coronaTex.bind(); - coronaTex.enable(); - for( Iterator it = nebulae.iterator(); it.hasNext(); ){ - Nebula n = (Nebula) it.next(); - if( !n.ISDEAD ){ - n.exist(); - } - else { - it.remove(); - } - } - coronaTex.disable(); - } - - - void render(){ - // pgl.bindTexture( images.emitter ); - emitterTex.bind(); - emitterTex.enable(); - renderImage( loc, radius, myColor, 1.0 ); - emitterTex.enable(); - - if( ALLOWNEBULA ){ - nebulae.add( new Nebula( loc, 15.0, true ) ); - nebulae.add( new Nebula( loc, 45.0, true ) ); - } - - - if( ALLOWFLOOR ){ - // pgl.bindTexture( images.reflection ); - reflectionTex.bind(); - reflectionTex.enable(); - renderReflection(); - reflectionTex.disable(); - } - } - - void renderReflection(){ - float altitude = floorLevel - loc.y; - float reflectMaxAltitude = 300.0; - float yPer = 1.0 - altitude/reflectMaxAltitude; - - if( yPer > .05 ) - renderImageOnFloor( new Vec3D( loc.x, floorLevel, loc.z ), radius * 10.0, color( 0.5, 1.0, yPer*.25 ), yPer ); - - if( mousePressed ) - renderImageOnFloor( new Vec3D( loc.x, floorLevel, loc.z ), radius + ( yPer + 1.0 ) * radius * random( 2.0, 3.5 ), color( 1.0, 0, 0 ), yPer ); - } - - void iterateListRenderTrails(){ - for( Iterator it = particles.iterator(); it.hasNext(); ){ - Particle p = (Particle) it.next(); - p.renderTrails(); - } - } - - void addParticles( int _amt ){ - for( int i=0; i<_amt; i++ ){ - particles.add( new Particle( 1, loc, vel ) ); - } - - if( ALLOWNEBULA ){ - nebulae.add( new Nebula( loc, 40.0, false ) ); - nebulae.add( new Nebula( loc, 100.0, false ) ); - } - } - - void addParticles( Particle _p ){ - // play with amt if you want to control how many particles spawn when splitting - int amt = (int)( _p.radius * .15 ); - for( int i=0; i maxNoise) maxNoise = rads; - - rads -= minNoise; - rads *= 1.0/(maxNoise - minNoise); - - return rads * mult; -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/images.pde b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/images.pde deleted file mode 100644 index 821c91230..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/images.pde +++ /dev/null @@ -1,13 +0,0 @@ -class Images{ - PImage particle; - PImage emitter; - PImage corona; - PImage reflection; - - Images(){ - particle = loadImage( "particle.png" ); - emitter = loadImage( "emitter.png" ); - corona = loadImage( "corona.png" ); - reflection = loadImage( "reflection.png" ); - } -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/nebula.pde b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/nebula.pde deleted file mode 100644 index 573378708..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/nebula.pde +++ /dev/null @@ -1,56 +0,0 @@ -class Nebula{ - Vec3D loc; - Vec3D vel; - float radius; - float scaleFac; - float age; - int lifeSpan; - float agePer; - float rot; - color c; - - boolean ISDEAD; - boolean ISGROUNDED; - - Nebula( Vec3D _loc, float _radius, boolean _ISGROUNDED ){ - loc = new Vec3D( _loc ); - vel = new Vec3D( pov.eyeNormal.scale( 2.0 ) ); - radius = random( _radius*.8, _radius*1.75 ); - - scaleFac = random( 1.005, 1.10 ); - age = 0; - lifeSpan = (int)random(10,30); - rot = random( TWO_PI ); - c = color( random(.75, 1.0), random(.5,.75), random(.2,.8) ); - ISGROUNDED = _ISGROUNDED; - - if( ISGROUNDED ){ - scaleFac = random( 1.01, 1.025 ); - vel.y -= random( 1.0 ); - radius *= 2.0; - } - } - - void exist(){ - move(); - render(); - checkAge(); - } - - void move(){ - radius *= scaleFac; - loc.addSelf( vel ); - } - - void render(){ - renderImageAndRotate( loc, radius, c, sin(agePer*PI) * .4, rot ); - } - - void checkAge(){ - age ++; - agePer = 1.0 - age/(float)lifeSpan; - - if (age > lifeSpan) - ISDEAD = true; - } -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/particle.pde b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/particle.pde deleted file mode 100644 index 53cbf839b..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/particle.pde +++ /dev/null @@ -1,171 +0,0 @@ - -class Particle{ - int len; // number of elements in position array - Vec3D[] loc; // array of position vectors - Vec3D startLoc; // just used to make sure every loc[] is initialized to the same position - Vec3D vel; // velocity vector - Vec3D perlin; // perlin noise vector - float radius; // particle's size - float age; // current age of particle - int lifeSpan; // max allowed age of particle - float agePer; // range from 1.0 (birth) to 0.0 (death) - int gen; // number of times particle has been involved in a SPLIT - float bounceAge; // amount to age particle when it bounces off floor - float bounceVel; // speed at impact - boolean ISDEAD; // if age == lifeSpan, make particle die - boolean ISBOUNCING; // if particle hits the floor... - boolean ISSPLIT; // if particle hits the floor with enough speed... - - - Particle( int _gen, Vec3D _loc, Vec3D _vel ){ - gen = _gen; - radius = random( 10 - gen, 50 - ( gen-1)*10 ); - - len = (int)( radius*.5 ); - loc = new Vec3D[ len ]; - startLoc = new Vec3D( _loc.add( new Vec3D().randomVector().scaleSelf( random( 1.0 ) ) ) ); - - for( int i=0; i 1 ){ - vel.addSelf( new Vec3D().randomVector().scaleSelf( random( 7.0 ) ) ); - } else { - vel.addSelf( new Vec3D().randomVector().scaleSelf( random( 10.0 ) ) ); - } - - perlin = new Vec3D(); - - age = 0; - bounceAge = 2; - lifeSpan = (int)( radius ); - } - - void exist(){ - if( ALLOWPERLIN ) - findPerlin(); - - findVelocity(); - setPosition(); - render(); - setAge(); - } - - void findPerlin(){ - float xyRads = getRads( loc[0].x, loc[0].z, 20.0, 50.0 ); - float yRads = getRads( loc[0].x, loc[0].y, 20.0, 50.0 ); - perlin.set( cos(xyRads), -sin(yRads), sin(xyRads) ); - perlin.scaleSelf( .5 ); - } - - void findVelocity(){ - if( ALLOWGRAVITY ) - vel.addSelf( gravity ); - - if( ALLOWPERLIN ) - vel.addSelf( perlin ); - - if( ALLOWFLOOR ){ - if( loc[0].y + vel.y > floorLevel ){ - ISBOUNCING = true; - } else { - ISBOUNCING = false; - } - } - - // if the particle is moving fast enough, when it hits the ground it can - // split into a bunch of smaller particles. - if( ISBOUNCING ){ - bounceVel = vel.magnitude(); - - vel.scaleSelf( .7 ); - vel.y *= -( ( radius/40.0 ) * .5 ); - - if( bounceVel > 15.0 && gen < 4 ) - ISSPLIT = true; - - } else { - ISSPLIT = false; - } - } - - void setPosition(){ - for( int i=len-1; i>0; i-- ){ - loc[i].set( loc[i-1] ); - } - - loc[0].addSelf( vel ); - } - - void render(){ - color c = color( agePer - .5, agePer*.25, 1.5 - agePer ); - renderImage( loc[0], radius * agePer, c, 1.0 ); - - // Rendering two graphics here. Makes the particles more vivid, - // but will hinder the performance. - c = color( 1, agePer, agePer ); - renderImage( loc[0], radius * agePer * .5, c, agePer ); - } - - void renderReflection(){ - float altitude = floorLevel - loc[0].y; - float reflectMaxAltitude = 25.0; - float yPer = ( 1.0 - ( altitude/reflectMaxAltitude ) ) * .5; - - if( yPer > .05 ) - renderImageOnFloor( new Vec3D( loc[0].x, floorLevel, loc[0].z ), radius * agePer * 8.0 * yPer, color( agePer, agePer*.25, 0 ), yPer + random( .2 ) ); - } - - void renderTrails(){ - float xp, yp, zp; - float xOff, yOff, zOff; - - gl.glBegin( GL.GL_QUAD_STRIP ); - - for ( int i=0; i lifeSpan ){ - ISDEAD = true; - } else { - agePer = 1.0 - age/(float)lifeSpan; - } - } -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/pov.pde b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/pov.pde deleted file mode 100644 index 1d5bf01d7..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/pov.pde +++ /dev/null @@ -1,62 +0,0 @@ -// Camera class which uses Kristian Damkjer's OCD library -// http://www.cise.ufl.edu/~kdamkjer/processing/libraries/ocd/ - -class POV{ - PApplet parent; - Camera cam; - - Vec3D eye; - Vec3D center; - - Vec3D eyeNormal; - - boolean ISDRAGGING; - - POV( PApplet _parent ){ - parent = _parent; - cam = new Camera( parent, 0, 100, 1500 ); - - eye = new Vec3D(); - center = new Vec3D(); - eyeNormal = new Vec3D(); - } - - void exist(){ - perspective( PI/3.0, (float)xSize/(float)ySize, .5, 5000 ); - if( ISDRAGGING ){ - cam.circle( radians( ( mouseX - pmouseX ) * .25 ) ); - cam.arc( radians( ( mouseY - pmouseY ) * .25 ) ); - } - - cam.feed(); - setPosition(); - } - - - // Code by JohnG from the Processing forum - // http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Programs;action=display;num=1170790832 - // - // Does the camera transformations in reverse to allow for images that always face the camera. - void glReverseCamera(){ - float deltaX = eye.x - center.x; - float deltaY = eye.y - center.y; - float deltaZ = eye.z - center.z; - - float angleZ = atan2( deltaY,deltaX ); - float hyp = sqrt( sq( deltaX ) + sq( deltaY ) ); - float angleY = atan2( hyp,deltaZ ); - - gl.glRotatef( degrees( angleZ ), 0, 0, 1.0 ); - gl.glRotatef( degrees( angleY ), 0, 1.0, 0 ); - } - - - void setPosition(){ - float[] e = cam.position(); - float[] c = cam.target(); - - eye.set( e[0], e[1], e[2] ); - center.set( c[0], c[1], c[2] ); - eyeNormal = eye.sub(center).normalize(); - } -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/sketch.properties b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/sketch.properties deleted file mode 100644 index 28faa5897..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_GLtexture/sketch.properties +++ /dev/null @@ -1 +0,0 @@ -mode=Standard diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/NOC_gl.pde b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/NOC_gl.pde deleted file mode 100644 index 44705cdbd..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/NOC_gl.pde +++ /dev/null @@ -1,31 +0,0 @@ - -void renderImage(PImage img, Vec3D _loc, float _diam, color _col, float _alpha ) { - pushMatrix(); - translate( _loc.x, _loc.y, _loc.z ); - pov.glReverseCamera(); - tint(red(_col), green(_col), blue(_col), _alpha); - imageMode(CENTER); - image(img,0,0,_diam,_diam); - popMatrix(); -} - -void renderImageOnFloor(PImage img, Vec3D _loc, float _diam, color _col, float _aa ) { - pushMatrix(); - translate( _loc.x, _loc.y, _loc.z ); - rotateX(PI/2); - //pov.glReverseCamera(); - tint(red(_col), green(_col), blue(_col), _aa); - imageMode(CENTER); - image(img,0,0,_diam,_diam); - popMatrix(); -} - -void renderImageAndRotate(PImage img, Vec3D _loc, float _diam, color _col, float _aa, float _rot ) { - pushMatrix(); - translate( _loc.x, _loc.y, _loc.z ); - pov.glReverseCamera(); - tint(red(_col), green(_col), blue(_col), _aa); - imageMode(CENTER); - image(img,0,0,_diam,_diam); - popMatrix(); -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/cursor.pde b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/cursor.pde deleted file mode 100644 index ee2909cb9..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/cursor.pde +++ /dev/null @@ -1,25 +0,0 @@ -class Cursor{ - Vec3D loc; - Vec3D vel; - - Cursor(){ - loc = new Vec3D(); - vel = new Vec3D(); - } - - void exist(){ - // 2.35 is an arbitrary number. Ideally, this cursor would function - // properly regardless of the camera's rotation and distance from the object. - // Im not sure how to make that happen... 3D interaction with the cursor has - // been low on my research list. Think of this as a crappy placeholder. - loc.set( ( mouseX - xMid ) * 2.25, ( mouseY - yMid ) * 2.25, 0 ); - } - - void render(){ - pushMatrix(); - translate( loc.x, loc.y, loc.z ); - fill( 1, 0, 0 ); - sphere( 10 ); - popMatrix(); - } -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/emitter.pde b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/emitter.pde deleted file mode 100644 index c22f45bdf..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/emitter.pde +++ /dev/null @@ -1,149 +0,0 @@ -class Emitter{ - Vec3D loc; - Vec3D vel; - Vec3D velToMouse; - float radius; - - color myColor; - - ArrayList particles; - ArrayList nebulae; - - Emitter( ){ - loc = new Vec3D(); - vel = new Vec3D(); - velToMouse = new Vec3D(); - - radius = 100; - - myColor = color( 1, 1, 1 ); - - particles = new ArrayList(); - nebulae = new ArrayList(); - } - - void exist(){ - findVelocity(); - setPosition(); - iterateListExist(); - render(); - - gl.glDisable( GL.GL_TEXTURE_2D ); - - if( ALLOWTRAILS ) - iterateListRenderTrails(); - } - - void findVelocity(){ - Vec3D dirToMouse = new Vec3D( mouse.loc.sub( loc ).scale( .15 ) ); - vel.set( dirToMouse ); - } - - void setPosition(){ - loc.addSelf( vel ); - - if( ALLOWFLOOR ){ - if( loc.y > floorLevel ){ - loc.y = floorLevel; - vel.y = 0; - } - } - } - - void iterateListExist(){ - gl.glEnable( GL.GL_TEXTURE_2D ); - - - int mylength = particles.size(); - for( int i=mylength-1; i>=0; i-- ){ - Particle p = ( Particle )particles.get(i); - if( p.ISSPLIT ) - addParticles( p ); - - if ( !p.ISDEAD ){ - //pgl.bindTexture( images.particle ); - p.exist(); - - } else { - particles.set( i, particles.get( particles.size() - 1 ) ); - particles.remove( particles.size() - 1 ); - } - } - - if( ALLOWFLOOR ){ - //pgl.bindTexture( images.reflection ); - for( Iterator it = particles.iterator(); it.hasNext(); ){ - Particle p = (Particle) it.next(); - p.renderReflection(); - } - } - - //pgl.bindTexture( images.corona ); - for( Iterator it = nebulae.iterator(); it.hasNext(); ){ - Nebula n = (Nebula) it.next(); - if( !n.ISDEAD ){ - n.exist(); - } else { - it.remove(); - } - } - } - - - void render(){ - //pgl.bindTexture( images.emitter ); - renderImage( images.emitter,loc, radius, myColor, 1.0 ); - - - if( ALLOWNEBULA ){ - nebulae.add( new Nebula( loc, 15.0, true ) ); - nebulae.add( new Nebula( loc, 45.0, true ) ); - } - - - if( ALLOWFLOOR ){ - //pgl.bindTexture( images.reflection ); - renderReflection(images.reflection); - } - } - - void renderReflection(PImage img){ - float altitude = floorLevel - loc.y; - float reflectMaxAltitude = 300.0; - float yPer = 1.0 - altitude/reflectMaxAltitude; - - if( yPer > .05 ) - renderImageOnFloor(img, new Vec3D( loc.x, floorLevel, loc.z ), radius * 10.0, color( 0.5, 1.0, yPer*.25 ), yPer ); - - if( mousePressed ) - renderImageOnFloor(img, new Vec3D( loc.x, floorLevel, loc.z ), radius + ( yPer + 1.0 ) * radius * random( 2.0, 3.5 ), color( 1.0, 0, 0 ), yPer ); - } - - void iterateListRenderTrails(){ - for( Iterator it = particles.iterator(); it.hasNext(); ){ - Particle p = (Particle) it.next(); - p.renderTrails(); - } - } - - void addParticles( int _amt ){ - for( int i=0; i<_amt; i++ ){ - particles.add( new Particle( 1, loc, vel ) ); - } - - if( ALLOWNEBULA ){ - nebulae.add( new Nebula( loc, 40.0, false ) ); - nebulae.add( new Nebula( loc, 100.0, false ) ); - } - } - - void addParticles( Particle _p ){ - // play with amt if you want to control how many particles spawn when splitting - int amt = (int)( _p.radius * .15 ); - for( int i=0; i maxNoise) maxNoise = rads; - - rads -= minNoise; - rads *= 1.0/(maxNoise - minNoise); - - return rads * mult; -} - diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/images.pde b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/images.pde deleted file mode 100644 index 821c91230..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/images.pde +++ /dev/null @@ -1,13 +0,0 @@ -class Images{ - PImage particle; - PImage emitter; - PImage corona; - PImage reflection; - - Images(){ - particle = loadImage( "particle.png" ); - emitter = loadImage( "emitter.png" ); - corona = loadImage( "corona.png" ); - reflection = loadImage( "reflection.png" ); - } -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/nebula.pde b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/nebula.pde deleted file mode 100644 index 3412c110f..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/nebula.pde +++ /dev/null @@ -1,56 +0,0 @@ -class Nebula{ - Vec3D loc; - Vec3D vel; - float radius; - float scaleFac; - float age; - int lifeSpan; - float agePer; - float rot; - color c; - - boolean ISDEAD; - boolean ISGROUNDED; - - Nebula( Vec3D _loc, float _radius, boolean _ISGROUNDED ){ - loc = new Vec3D( _loc ); - vel = new Vec3D( pov.eyeNormal.scale( 2.0 ) ); - radius = random( _radius*.8, _radius*1.75 ); - - scaleFac = random( 1.005, 1.10 ); - age = 0; - lifeSpan = (int)random(10,30); - rot = random( TWO_PI ); - c = color( random(.75, 1.0), random(.5,.75), random(.2,.8) ); - ISGROUNDED = _ISGROUNDED; - - if( ISGROUNDED ){ - scaleFac = random( 1.01, 1.025 ); - vel.y -= random( 1.0 ); - radius *= 2.0; - } - } - - void exist(){ - move(); - render(); - checkAge(); - } - - void move(){ - radius *= scaleFac; - loc.addSelf( vel ); - } - - void render(){ - renderImageAndRotate(images.corona, loc, radius, c, sin(agePer*PI) * .4, rot ); - } - - void checkAge(){ - age ++; - agePer = 1.0 - age/(float)lifeSpan; - - if (age > lifeSpan) - ISDEAD = true; - } -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/particle.pde b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/particle.pde deleted file mode 100644 index 893d3631f..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/particle.pde +++ /dev/null @@ -1,172 +0,0 @@ - -class Particle{ - int len; // number of elements in position array - Vec3D[] loc; // array of position vectors - Vec3D startLoc; // just used to make sure every loc[] is initialized to the same position - Vec3D vel; // velocity vector - Vec3D perlin; // perlin noise vector - float radius; // particle's size - float age; // current age of particle - int lifeSpan; // max allowed age of particle - float agePer; // range from 1.0 (birth) to 0.0 (death) - int gen; // number of times particle has been involved in a SPLIT - float bounceAge; // amount to age particle when it bounces off floor - float bounceVel; // speed at impact - boolean ISDEAD; // if age == lifeSpan, make particle die - boolean ISBOUNCING; // if particle hits the floor... - boolean ISSPLIT; // if particle hits the floor with enough speed... - - - Particle( int _gen, Vec3D _loc, Vec3D _vel ){ - gen = _gen; - radius = random( 10 - gen, 50 - ( gen-1)*10 ); - - len = (int)( radius*.5 ); - loc = new Vec3D[ len ]; - startLoc = new Vec3D( _loc.add( new Vec3D().randomVector().scaleSelf( random( 1.0 ) ) ) ); - - for( int i=0; i 1 ){ - vel.addSelf( new Vec3D().randomVector().scaleSelf( random( 7.0 ) ) ); - } else { - vel.addSelf( new Vec3D().randomVector().scaleSelf( random( 10.0 ) ) ); - } - - perlin = new Vec3D(); - - age = 0; - bounceAge = 2; - lifeSpan = (int)( radius ); - } - - void exist(){ - if( ALLOWPERLIN ) - findPerlin(); - - findVelocity(); - setPosition(); - render(); - setAge(); - } - - void findPerlin(){ - float xyRads = getRads( loc[0].x, loc[0].z, 20.0, 50.0 ); - float yRads = getRads( loc[0].x, loc[0].y, 20.0, 50.0 ); - perlin.set( cos(xyRads), -sin(yRads), sin(xyRads) ); - perlin.scaleSelf( .5 ); - } - - void findVelocity(){ - if( ALLOWGRAVITY ) - vel.addSelf( gravity ); - - if( ALLOWPERLIN ) - vel.addSelf( perlin ); - - if( ALLOWFLOOR ){ - if( loc[0].y + vel.y > floorLevel ){ - ISBOUNCING = true; - } else { - ISBOUNCING = false; - } - } - - // if the particle is moving fast enough, when it hits the ground it can - // split into a bunch of smaller particles. - if( ISBOUNCING ){ - bounceVel = vel.magnitude(); - - vel.scaleSelf( .7 ); - vel.y *= -( ( radius/40.0 ) * .5 ); - - if( bounceVel > 15.0 && gen < 4 ) - ISSPLIT = true; - - } else { - ISSPLIT = false; - } - } - - void setPosition(){ - for( int i=len-1; i>0; i-- ){ - loc[i].set( loc[i-1] ); - } - - loc[0].addSelf( vel ); - } - - void render(){ - color c = color( agePer - .5, agePer*.25, 1.5 - agePer ); - renderImage(images.particle, loc[0], radius * agePer, c, 1.0 ); - - // Rendering two graphics here. Makes the particles more vivid, - // but will hinder the performance. - c = color( 1, agePer, agePer ); - renderImage(images.particle, loc[0], radius * agePer * .5, c, agePer ); - } - - void renderReflection(){ - float altitude = floorLevel - loc[0].y; - float reflectMaxAltitude = 25.0; - float yPer = ( 1.0 - ( altitude/reflectMaxAltitude ) ) * .5; - - if( yPer > .05 ) - renderImageOnFloor(images.particle, new Vec3D( loc[0].x, floorLevel, loc[0].z ), radius * agePer * 8.0 * yPer, color( agePer, agePer*.25, 0 ), yPer + random( .2 ) ); - } - - void renderTrails(){ - float xp, yp, zp; - float xOff, yOff, zOff; - - beginShape(QUAD_STRIP); - - for ( int i=0; i lifeSpan ){ - ISDEAD = true; - } else { - agePer = 1.0 - age/(float)lifeSpan; - } - } -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/pov.pde b/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/pov.pde deleted file mode 100644 index cc41c1360..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/flight404/flight404_particles_2_simple/pov.pde +++ /dev/null @@ -1,64 +0,0 @@ -// Camera class which uses Kristian Damkjer's OCD library -// http://www.cise.ufl.edu/~kdamkjer/processing/libraries/ocd/ - -class POV{ - PApplet parent; - Camera cam; - - Vec3D eye; - Vec3D center; - - Vec3D eyeNormal; - - boolean ISDRAGGING; - - POV( PApplet _parent ){ - parent = _parent; - cam = new Camera( parent, 0, -100, 1500 ); - - eye = new Vec3D(); - center = new Vec3D(); - eyeNormal = new Vec3D(); - } - - void exist(){ - perspective( PI/3.0, (float)xSize/(float)ySize, .5, 5000 ); - if( ISDRAGGING ){ - cam.circle( radians( ( mouseX - pmouseX ) * .25 ) ); - cam.arc( radians( ( mouseY - pmouseY ) * .25 ) ); - } - - cam.feed(); - setPosition(); - } - - - // Code by JohnG from the Processing forum - // http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Programs;action=display;num=1170790832 - // - // Does the camera transformations in reverse to allow for images that always face the camera. - void glReverseCamera(){ - float deltaX = eye.x - center.x; - float deltaY = eye.y - center.y; - float deltaZ = eye.z - center.z; - - float angleZ = atan2( deltaY,deltaX ); - float hyp = sqrt( sq( deltaX ) + sq( deltaY ) ); - float angleY = atan2( hyp,deltaZ ); - - rotateZ(angleZ); - rotateY(angleY); - //gl.glRotatef( degrees( angleZ ), 0, 0, 1.0 ); - //gl.glRotatef( degrees( angleY ), 0, 1.0, 0 ); - } - - - void setPosition(){ - float[] e = cam.position(); - float[] c = cam.target(); - - eye.set( e[0], e[1], e[2] ); - center.set( c[0], c[1], c[2] ); - eyeNormal = eye.sub(center).normalize(); - } -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/simpleInheritance/Circle.pde b/java/examples/Books/Nature of Code/chp4_systems/simpleInheritance/Circle.pde deleted file mode 100644 index a25a7fa3d..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/simpleInheritance/Circle.pde +++ /dev/null @@ -1,36 +0,0 @@ -// Learning Processing -// Daniel Shiffman -// http://www.learningprocessing.com - -// Example 22-1: Inheritance - -class Circle extends Shape { - - // Inherits all instance variables from parent + adding one - color c; - - Circle(float x_, float y_, float r_, color c_) { - super(x_,y_,r_); // Call the parent constructor - c = c_; // Also deal with this new instance variable - } - - // Call the parent jiggle, but do some more stuff too - void jiggle() { - super.jiggle(); - // The Circle jiggles its size as well as its x,y location. - r += random(-1,1); - r = constrain(r,0,100); - } - - // The changeColor() function is unique to the Circle class. - void changeColor() { - c = color(random(255)); - } - - void display() { - ellipseMode(CENTER); - fill(c); - stroke(0); - ellipse(x,y,r,r); - } -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/simpleInheritance/Shape.pde b/java/examples/Books/Nature of Code/chp4_systems/simpleInheritance/Shape.pde deleted file mode 100644 index a4d8a723a..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/simpleInheritance/Shape.pde +++ /dev/null @@ -1,28 +0,0 @@ -// Learning Processing -// Daniel Shiffman -// http://www.learningprocessing.com - -// Example 22-1: Inheritance - -class Shape { - float x; - float y; - float r; - - Shape(float x_, float y_, float r_) { - x = x_; - y = y_; - r = r_; - } - - void jiggle() { - x += random(-1,1); - y += random(-1,1); - } - - // A generic shape does not really know how to be displayed. - // This will be overridden in the child classes. - void display() { - point(x,y); - } -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/simpleInheritance/Square.pde b/java/examples/Books/Nature of Code/chp4_systems/simpleInheritance/Square.pde deleted file mode 100644 index 51209d3da..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/simpleInheritance/Square.pde +++ /dev/null @@ -1,25 +0,0 @@ -// Learning Processing -// Daniel Shiffman -// http://www.learningprocessing.com - -// Example 22-1: Inheritance - -class Square extends Shape { - // Variables are inherited from the parent. - // We could also add variables unique to the Square class if we so desire - - Square(float x_, float y_, float r_) { - // If the parent constructor takes arguments then super() needs to pass in those arguments. - super(x_,y_,r_); - } - - // Inherits jiggle() from parent - - // The square overrides its parent for display. - void display() { - rectMode(CENTER); - fill(175); - stroke(0); - rect(x,y,r,r); - } -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/simpleInheritance/simpleInheritance.pde b/java/examples/Books/Nature of Code/chp4_systems/simpleInheritance/simpleInheritance.pde deleted file mode 100644 index f5ff6dd60..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/simpleInheritance/simpleInheritance.pde +++ /dev/null @@ -1,27 +0,0 @@ -// Learning Processing -// Daniel Shiffman -// http://www.learningprocessing.com - -// Example 22-1: Inheritance - -// Object oriented programming allows us to defi ne classes in terms of other classes. -// A class can be a subclass (aka " child " ) of a super class (aka "parent"). -// This is a simple example demonstrating this concept, known as "inheritance." -Square s; -Circle c; - -void setup() { - size(200,200); - smooth(); - // A square and circle - s = new Square(75,75,10); - c = new Circle(125,125,20,color(175)); -} - -void draw() { - background(255); - c.jiggle(); - s.jiggle(); - c.display(); - s.display(); -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/simplePolymorphism/Circle.pde b/java/examples/Books/Nature of Code/chp4_systems/simplePolymorphism/Circle.pde deleted file mode 100644 index 538f27a4a..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/simplePolymorphism/Circle.pde +++ /dev/null @@ -1,36 +0,0 @@ -// Learning Processing -// Daniel Shiffman -// http://www.learningprocessing.com - -// Example 22-2: Polymorphism - -class Circle extends Shape { - - // Inherits all instance variables from parent + adding one - color c; - - Circle(float x_, float y_, float r_, color c_) { - super(x_,y_,r_); // Call the parent constructor - c = c_; // Also deal with this new instance variable - } - - // Call the parent jiggle, but do some more stuff too - void jiggle() { - super.jiggle(); - // The Circle jiggles its size as well as its x,y location. - r += random(-1,1); - r = constrain(r,0,100); - } - - // The changeColor() function is unique to the Circle class. - void changeColor() { - c = color(random(255)); - } - - void display() { - ellipseMode(CENTER); - fill(c); - stroke(0); - ellipse(x,y,r,r); - } -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/simplePolymorphism/Shape.pde b/java/examples/Books/Nature of Code/chp4_systems/simplePolymorphism/Shape.pde deleted file mode 100644 index 54c7fe4a3..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/simplePolymorphism/Shape.pde +++ /dev/null @@ -1,28 +0,0 @@ -// Learning Processing -// Daniel Shiffman -// http://www.learningprocessing.com - -// Example 22-2: Polymorphism - -class Shape { - float x; - float y; - float r; - - Shape(float x_, float y_, float r_) { - x = x_; - y = y_; - r = r_; - } - - void jiggle() { - x += random(-1,1); - y += random(-1,1); - } - - // A generic shape does not really know how to be displayed. - // This will be overridden in the child classes. - void display() { - point(x,y); - } -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/simplePolymorphism/Square.pde b/java/examples/Books/Nature of Code/chp4_systems/simplePolymorphism/Square.pde deleted file mode 100644 index 489b99073..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/simplePolymorphism/Square.pde +++ /dev/null @@ -1,25 +0,0 @@ -// Learning Processing -// Daniel Shiffman -// http://www.learningprocessing.com - -// Example 22-2: Polymorphism - -class Square extends Shape { - // Variables are inherited from the parent. - // We could also add variables unique to the Square class if we so desire - - Square(float x_, float y_, float r_) { - // If the parent constructor takes arguments then super() needs to pass in those arguments. - super(x_,y_,r_); - } - - // Inherits jiggle() from parent - - // The square overrides its parent for display. - void display() { - rectMode(CENTER); - fill(175); - stroke(0); - rect(x,y,r,r); - } -} diff --git a/java/examples/Books/Nature of Code/chp4_systems/simplePolymorphism/simplePolymorphism.pde b/java/examples/Books/Nature of Code/chp4_systems/simplePolymorphism/simplePolymorphism.pde deleted file mode 100644 index add4ed517..000000000 --- a/java/examples/Books/Nature of Code/chp4_systems/simplePolymorphism/simplePolymorphism.pde +++ /dev/null @@ -1,32 +0,0 @@ -// Learning Processing -// Daniel Shiffman -// http://www.learningprocessing.com - -// Example 22-2: Polymorphism - -// One array of Shapes -Shape[] shapes = new Shape[30]; - -void setup() { - size(200,200); - smooth(); - - for (int i = 0; i < shapes.length; i++ ) { - int r = int(random(2)); - // Randomly put either circles or squares in our array - if (r == 0) { - shapes[i] = new Circle(100,100,10,color(random(255),100)); - } else { - shapes[i] = new Square(100,100,10); - } - } -} - -void draw() { - background(255); - // Jiggle and display all shapes - for (int i = 0; i < shapes.length; i++ ) { - shapes[i].jiggle(); - shapes[i].display(); - } -} diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/CollisionsEqualMass/CollisionsEqualMass.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/CollisionsEqualMass/CollisionsEqualMass.pde deleted file mode 100644 index 4abce573e..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/CollisionsEqualMass/CollisionsEqualMass.pde +++ /dev/null @@ -1,33 +0,0 @@ -// Collisions -- Elastic, Equal Mass, Two objects only -// Nature of Code, Spring 2009 -// Daniel Shiffman - -// Based off of Chapter 9: Resolving Collisions -// Mathematics and Physics for Programmers by Danny Kodicek - -// A Thing class for idealized collisions - -Mover a; -Mover b; - -boolean showVectors = true; - -void setup() { - size(200,200); - smooth(); - a = new Mover(new PVector(random(5),random(-5,5)),new PVector(10,10)); - b = new Mover(new PVector(-2,1),new PVector(150,150)); -} - -void draw() { - background(255); - a.go(); - b.go(); - - // Note this function will ONLY WORK with two objects - // Needs to be revised in the case of an array of objects - a.collideEqualMass(b); -} - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/CollisionsEqualMass/Mover.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/CollisionsEqualMass/Mover.pde deleted file mode 100644 index 48d6389b3..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/CollisionsEqualMass/Mover.pde +++ /dev/null @@ -1,99 +0,0 @@ -// Collisions -// Daniel Shiffman - -// A Thing class for idealized collision - -class Mover { - - PVector loc; - PVector vel; - float bounce = 1.0; - float r = 20; - boolean colliding = false; - - Mover(PVector v, PVector l) { - vel = v.get(); - loc = l.get(); - } - - // Main method to operate object - void go() { - update(); - borders(); - display(); - } - - // Method to update location - void update() { - loc.add(vel); - } - - // Check for bouncing off borders - void borders() { - if (loc.y > height) { - vel.y *= -bounce; - loc.y = height; - } - else if (loc.y < 0) { - vel.y *= -bounce; - loc.y = 0; - } - if (loc.x > width) { - vel.x *= -bounce; - loc.x = width; - } - else if (loc.x < 0) { - vel.x *= -bounce; - loc.x = 0; - } - } - - // Method to display - void display() { - ellipseMode(CENTER); - stroke(0); - fill(175,200); - ellipse(loc.x,loc.y,r*2,r*2); - if (showVectors) { - drawVector(vel,loc,10); - } - } - - void collideEqualMass(Mover other) { - float d = PVector.dist(loc,other.loc); - float sumR = r + other.r; - // Are they colliding? - if (!colliding && d < sumR) { - // Yes, make new velocities! - colliding = true; - // Direction of one object another - PVector n = PVector.sub(other.loc,loc); - n.normalize(); - - // Difference of velocities so that we think of one object as stationary - PVector u = PVector.sub(vel,other.vel); - - // Separate out components -- one in direction of normal - PVector un = componentVector(u,n); - // Other component - u.sub(un); - // These are the new velocities plus the velocity of the object we consider as stastionary - vel = PVector.add(u,other.vel); - other.vel = PVector.add(un,other.vel); - } - else if (d > sumR) { - colliding = false; - } - } -} - -PVector componentVector (PVector vector, PVector directionVector) { - //--! ARGUMENTS: vector, directionVector (2D vectors) - //--! RETURNS: the component vector of vector in the direction directionVector - //-- normalize directionVector - directionVector.normalize(); - directionVector.mult(vector.dot(directionVector)); - return directionVector; -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/CollisionsEqualMass/drawVector.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/CollisionsEqualMass/drawVector.pde deleted file mode 100644 index c3440240d..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/CollisionsEqualMass/drawVector.pde +++ /dev/null @@ -1,21 +0,0 @@ -void drawVector(PVector v, PVector loc, float scayl) { - pushMatrix(); - float arrowsize = 4; - // Translate to location to render vector - translate(loc.x,loc.y); - stroke(0); - // Call vector heading function to get direction (note that pointing up is a heading of 0) and rotate - rotate(v.heading2D()); - // Calculate length of vector & scale it to be bigger or smaller if necessary - float len = v.mag()*scayl; - // Draw three lines to make an arrow (draw pointing up since we've rotate to the proper direction) - line(0,0,len,0); - line(len,0,len-arrowsize,+arrowsize/2); - line(len,0,len-arrowsize,-arrowsize/2); - popMatrix(); -} - - -void mousePressed() { - showVectors = !showVectors; -} diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/Blob.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/Blob.pde deleted file mode 100644 index 43c0584a0..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/Blob.pde +++ /dev/null @@ -1,196 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A blob skeleton -// Could be used to create blobbly characters a la Nokia Friends -// http://postspectacular.com/work/nokia/friends/start - -class Skeleton { - - // A list to keep track of all the bodies and joints - ArrayList bodies; - ArrayList joints; - - float bodyRadius; // The radius of each body that makes up the skeleton - float radius; // The radius of the entire blob - float totalPoints; // How many points make up the blob - - - // We should modify this constructor to receive arguments - // So that we can make many different types of blobs - Skeleton() { - - // Create the empty ArrayLists - bodies = new ArrayList(); - joints = new ArrayList(); - - // Where and how big is the blob - Vec2 center = new Vec2(width/2, height/2); - radius = 100; - totalPoints = 32; - bodyRadius = 10; - - // Initialize all the points in a circle - for (int i = 0; i < totalPoints; i++) { - // Look polar to cartesian coordinate transformation! - float theta = PApplet.map(i, 0, totalPoints, 0, TWO_PI); - float x = center.x + radius * sin(theta); - float y = center.y + radius * cos(theta); - - // Make each individual body - BodyDef bd = new BodyDef(); - bd.type = BodyType.DYNAMIC; - - bd.fixedRotation = true; // no rotation! - bd.position.set(box2d.coordPixelsToWorld(x, y)); - Body body = box2d.createBody(bd); - - // The body is a circle - CircleShape cs = new CircleShape(); - cs.m_radius = box2d.scalarPixelsToWorld(bodyRadius); - - // Define a fixture - FixtureDef fd = new FixtureDef(); - fd.shape = cs; - fd.density = 1; - fd.friction = 0.5; - fd.restitution = 0.3; - - // Finalize the body - body.createFixture(fd); - - // Store our own copy for later rendering - bodies.add(body); - } - - // Now connect the outline of the shape all with joints - for (int i = 0; i < bodies.size(); i++) { - DistanceJointDef djd = new DistanceJointDef(); - Body a = bodies.get(i); - int next = i+1; - if (i == bodies.size()-1) { - next = 0; - } - Body b = bodies.get(next); - // Connection between previous particle and this one - djd.bodyA = a; - djd.bodyB = b; - // Equilibrium length is distance between these bodies - Vec2 apos = a.getWorldCenter(); - Vec2 bpos = b.getWorldCenter(); - float d = dist(apos.x, apos.y, bpos.x, bpos.y); - djd.length = d; - // These properties affect how springy the joint is - djd.frequencyHz = 10; - djd.dampingRatio = 0.9; - - // Make the joint. - DistanceJoint dj = (DistanceJoint) box2d.world.createJoint(djd); - joints.add(dj); - } - - - // Make some joints that cross the center of the blob between bodies - for (int i = 0; i < bodies.size(); i++) { - for (int j = i+2; j < bodies.size(); j+=4) { - DistanceJointDef djd = new DistanceJointDef(); - Body a = bodies.get(i); - Body b = bodies.get(j); - // Connection between two bides - djd.bodyA = a; - djd.bodyB = b; - // Equilibrium length is distance between these bodies - Vec2 apos = a.getWorldCenter(); - Vec2 bpos = b.getWorldCenter(); - float d = dist(apos.x, apos.y, bpos.x, bpos.y); - - djd.length = d; - // These properties affect how springy the joint is - djd.frequencyHz = 3; - djd.dampingRatio = 0.1; - - // Make the joint. - DistanceJoint dj = (DistanceJoint) box2d.world.createJoint(djd); - joints.add(dj); - } - } - } - - - // Draw the skeleton as circles for bodies and lines for joints - void displaySkeleton() { - // Draw the outline - stroke(0); - strokeWeight(1); - for (Joint j: joints) { - Body a = j.getBodyA(); - Body b = j.getBodyB(); - Vec2 posa = box2d.getBodyPixelCoord(a); - Vec2 posb = box2d.getBodyPixelCoord(b); - line(posa.x, posa.y, posb.x, posb.y); - } - - // Draw the individual circles - for (Body b: bodies) { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(b); - // Get its angle of rotation - float a = b.getAngle(); - pushMatrix(); - translate(pos.x, pos.y); - rotate(a); - fill(175); - stroke(0); - strokeWeight(1); - ellipse(0, 0, bodyRadius*2, bodyRadius*2); - popMatrix(); - } - } - - - // Draw it as a creature - void displayCreature() { - // Let's compute the center! - Vec2 center = new Vec2(0, 0); - - // Make a curvy polygon - beginShape(); - stroke(175); - strokeWeight(bodyRadius*2); - fill(175); - for (Body b: bodies) { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(b); - curveVertex(pos.x, pos.y); - center.addLocal(pos); - } - endShape(CLOSE); - // Center is average of all points - center.mulLocal(1.0/bodies.size()); - - // Find angle between center and side body - Vec2 pos = box2d.getBodyPixelCoord(bodies.get(0)); - float dx = pos.x - center.x; - float dy = pos.y - center.y; - float angle = atan2(dy, dx)-PI/2; - - // Draw eyes and mouth relative to center - pushMatrix(); - strokeWeight(1); - stroke(0); - translate(center.x, center.y); - rotate(angle); - fill(0); - ellipse(-25, -50, 16, 16); - ellipse(25, -50, 16, 16); - line(-50, 50, 50, 50); - popMatrix(); - } - - Body getFirstBody() { - return bodies.get(0); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/BlobSkeleton.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/BlobSkeleton.pde deleted file mode 100644 index b22248de8..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/BlobSkeleton.pde +++ /dev/null @@ -1,112 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A blob skeleton -// Could be used to create blobbly characters a la Nokia Friends -// http://postspectacular.com/work/nokia/friends/start - -import pbox2d.*; - -import org.jbox2d.collision.shapes.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; -import org.jbox2d.dynamics.joints.*; - -// A reference to our box2d world -PBox2D box2d; - -// A list we'll use to track fixed objects -ArrayList boundaries; - -// Our "blob" object -Skeleton blob; - -// Just a single box this time -Box box; -// The Spring that will attach to the box from the mouse -Spring spring; - -// Draw creature design or skeleton? -boolean skeleton; - -void setup() { - size(640, 360); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - - // Add some boundaries - boundaries = new ArrayList(); - boundaries.add(new Boundary(width/2, height-5, width, 10)); - boundaries.add(new Boundary(width/2, 5, width, 10)); - boundaries.add(new Boundary(width-5, height/2, 10, height)); - boundaries.add(new Boundary(5, height/2, 10, height)); - - // Make a new blob - blob = new Skeleton(); - - // Make the box - box = new Box(width/2, 100); - - // Make the spring (it doesn't really get initialized until the mouse is clicked) - spring = new Spring(); -} - -// When the mouse is released we're done with the spring -void mouseReleased() { - spring.destroy(); -} - -// When the mouse is pressed we. . . -void mousePressed() { - // Check to see if the mouse was clicked on the box - if (box.contains(mouseX, mouseY)) { - // And if so, bind the mouse location to the box with a spring - spring.bind(mouseX, mouseY, box); - } -} - -void draw() { - background(255); - - // We must always step through time! - - box2d.step(); - - - // Show the blob! - if (skeleton) { - blob.displaySkeleton(); - } - else { - blob.displayCreature(); - } - - // Show the boundaries! - for (Boundary wall: boundaries) { - wall.display(); - } - - // Always alert the spring to the new mouse location - spring.update(mouseX, mouseY); - - // Draw the box - box.display(); - // Draw the spring (it only appears when active) - spring.display(); - - fill(0); - text("Space bar to toggle creature/skeleton.\nClick and drag the box.", 20, height-30); -} - - -void keyPressed() { - if (key == ' ') { - skeleton = !skeleton; - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/Boundary.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/Boundary.pde deleted file mode 100644 index 7b5012517..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/Boundary.pde +++ /dev/null @@ -1,54 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A fixed boundary class - -class Boundary { - - // A boundary is a simple rectangle with x,y,width,and height - float x; - float y; - float w; - float h; - - // But we also have to make a body for box2d to know about it - Body b; - - Boundary(float x_,float y_, float w_, float h_) { - x = x_; - y = y_; - w = w_; - h = h_; - - // Define the polygon - PolygonShape sd = new PolygonShape(); - // Figure out the box2d coordinates - float box2dW = box2d.scalarPixelsToWorld(w/2); - float box2dH = box2d.scalarPixelsToWorld(h/2); - // We're just a box - sd.setAsBox(box2dW, box2dH); - - - // Create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.STATIC; - bd.position.set(box2d.coordPixelsToWorld(x,y)); - b = box2d.createBody(bd); - - // Attached the shape to the body using a Fixture - b.createFixture(sd,1); - } - - // Draw the boundary, if it were at an angle we'd have to do something fancier - void display() { - fill(0); - stroke(0); - rectMode(CENTER); - rect(x,y,w,h); - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/Box.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/Box.pde deleted file mode 100644 index b38eecedf..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/Box.pde +++ /dev/null @@ -1,86 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A rectangular box - -class Box { - - // We need to keep track of a Body and a width and height - Body body; - float w; - float h; - - // Constructor - Box(float x_, float y_) { - float x = x_; - float y = y_; - w = 50; - h = 50; - // Add the box to the box2d world - makeBody(new Vec2(x, y), w, h); - body.setUserData(this); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - boolean contains(float x, float y) { - Vec2 worldPoint = box2d.coordPixelsToWorld(x, y); - Fixture f = body.getFixtureList(); - boolean inside = f.testPoint(worldPoint); - return inside; - } - - // Drawing the box - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - - rectMode(PConstants.CENTER); - pushMatrix(); - translate(pos.x, pos.y); - rotate(-a); - fill(50); - stroke(0); - rect(0, 0, w, h); - popMatrix(); - } - - // This function adds the rectangle to the box2d world - void makeBody(Vec2 center, float w_, float h_) { - // Define and create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.DYNAMIC; - bd.position.set(box2d.coordPixelsToWorld(center)); - body = box2d.createBody(bd); - - // Define a polygon (this is what we use for a rectangle) - PolygonShape sd = new PolygonShape(); - float box2dW = box2d.scalarPixelsToWorld(w_/2); - float box2dH = box2d.scalarPixelsToWorld(h_/2); - sd.setAsBox(box2dW, box2dH); - - // Define a fixture - FixtureDef fd = new FixtureDef(); - fd.shape = sd; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.3; - fd.restitution = 0.5; - - body.createFixture(fd); - //body.setMassFromShapes(); - - // Give it some initial random velocity - body.setLinearVelocity(new Vec2(random(-5, 5), random(2, 5))); - body.setAngularVelocity(random(-5, 5)); - } -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/Spring.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/Spring.pde deleted file mode 100644 index 5fc777cc2..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/BlobSkeleton/Spring.pde +++ /dev/null @@ -1,76 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// Class to describe the spring joint (displayed as a line) - -class Spring { - - // This is the box2d object we need to create - MouseJoint mouseJoint; - - Spring() { - // At first it doesn't exist - mouseJoint = null; - } - - // If it exists we set its target to the mouse location - void update(float x, float y) { - if (mouseJoint != null) { - // Always convert to world coordinates! - Vec2 mouseWorld = box2d.coordPixelsToWorld(x,y); - mouseJoint.setTarget(mouseWorld); - } - } - - void display() { - if (mouseJoint != null) { - // We can get the two anchor points - Vec2 v1 = new Vec2(0,0); - mouseJoint.getAnchorA(v1); - Vec2 v2 = new Vec2(0,0); - mouseJoint.getAnchorB(v2); - // Convert them to screen coordinates - v1 = box2d.coordWorldToPixels(v1); - v2 = box2d.coordWorldToPixels(v2); - // And just draw a line - stroke(0); - strokeWeight(1); - line(v1.x,v1.y,v2.x,v2.y); - } - } - - - // This is the key function where - // we attach the spring to an x,y location - // and the Box object's location - void bind(float x, float y, Box box) { - // Define the joint - MouseJointDef md = new MouseJointDef(); - // Body A is just a fake ground body for simplicity (there isn't anything at the mouse) - md.bodyA = box2d.getGroundBody(); - // Body 2 is the box's boxy - md.bodyB = box.body; - // Get the mouse location in world coordinates - Vec2 mp = box2d.coordPixelsToWorld(x,y); - // And that's the target - md.target.set(mp); - // Some stuff about how strong and bouncy the spring should be - md.maxForce = 1000.0 * box.body.m_mass; - md.frequencyHz = 5.0; - md.dampingRatio = 0.9; - - // Make the joint! - mouseJoint = (MouseJoint) box2d.world.createJoint(md); - } - - void destroy() { - // We can get rid of the joint when the mouse is released - if (mouseJoint != null) { - box2d.world.destroyJoint(mouseJoint); - mouseJoint = null; - } - } - -} diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Blobby/Blob.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Blobby/Blob.pde deleted file mode 100644 index 3cc99fb8b..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Blobby/Blob.pde +++ /dev/null @@ -1,117 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A blob skeleton -// Could be used to create blobbly characters a la Nokia Friends -// http://postspectacular.com/work/nokia/friends/start - -class Blob { - - // A list to keep track of all the points in our blob - ArrayList skeleton; - - float bodyRadius; // The radius of each body that makes up the skeleton - float radius; // The radius of the entire blob - float totalPoints; // How many points make up the blob - - - // We should modify this constructor to receive arguments - // So that we can make many different types of blobs - Blob() { - - // Create the empty - skeleton = new ArrayList(); - - // Let's make a volume of joints! - ConstantVolumeJointDef cvjd = new ConstantVolumeJointDef(); - - // Where and how big is the blob - Vec2 center = new Vec2(width/2, height/2); - radius = 100; - totalPoints = 20; - bodyRadius = 12; - - - // Initialize all the points - for (int i = 0; i < totalPoints; i++) { - // Look polar to cartesian coordinate transformation! - float theta = PApplet.map(i, 0, totalPoints, 0, TWO_PI); - float x = center.x + radius * sin(theta); - float y = center.y + radius * cos(theta); - - // Make each individual body - BodyDef bd = new BodyDef(); - bd.type = BodyType.DYNAMIC; - - bd.fixedRotation = true; // no rotation! - bd.position.set(box2d.coordPixelsToWorld(x, y)); - Body body = box2d.createBody(bd); - - // The body is a circle - CircleShape cs = new CircleShape(); - cs.m_radius = box2d.scalarPixelsToWorld(bodyRadius); - - // Define a fixture - FixtureDef fd = new FixtureDef(); - fd.shape = cs; - - // For filtering out collisions - //fd.filter.groupIndex = -2; - - // Parameters that affect physics - fd.density = 1; - - // Finalize the body - body.createFixture(fd); - // Add it to the volume - cvjd.addBody(body); - - - // Store our own copy for later rendering - skeleton.add(body); - } - - // These parameters control how stiff vs. jiggly the blob is - cvjd.frequencyHz = 10.0f; - cvjd.dampingRatio = 1.0f; - - // Put the joint thing in our world! - box2d.world.createJoint(cvjd); - } - - - // Time to draw the blob! - // Can you make it a cute character, a la http://postspectacular.com/work/nokia/friends/start - void display() { - - // Draw the outline - beginShape(); - noFill(); - stroke(0); - strokeWeight(1); - for (Body b: skeleton) { - Vec2 pos = box2d.getBodyPixelCoord(b); - vertex(pos.x, pos.y); - } - endShape(CLOSE); - - // Draw the individual circles - for (Body b: skeleton) { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(b); - // Get its angle of rotation - float a = b.getAngle(); - pushMatrix(); - translate(pos.x, pos.y); - rotate(a); - fill(175); - stroke(0); - strokeWeight(1); - ellipse(0, 0, bodyRadius*2, bodyRadius*2); - popMatrix(); - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Blobby/Blobby.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Blobby/Blobby.pde deleted file mode 100644 index 8ebcdbfda..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Blobby/Blobby.pde +++ /dev/null @@ -1,66 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A blob skeleton -// Could be used to create blobbly characters a la Nokia Friends -// http://postspectacular.com/work/nokia/friends/start - -// This seems to be broken with the Box2D 2.1.2 version I'm using - -import pbox2d.*; - -import org.jbox2d.collision.shapes.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; -import org.jbox2d.dynamics.joints.*; - -// A reference to our box2d world -PBox2D box2d; - -// A list we'll use to track fixed objects -ArrayList boundaries; - -// Our "blob" object -Blob blob; - - void setup() { - size(400,300); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - - // Add some boundaries - boundaries = new ArrayList(); - boundaries.add(new Boundary(width/2,height-5,width,10)); - boundaries.add(new Boundary(width/2,5,width,10)); - boundaries.add(new Boundary(width-5,height/2,10,height)); - boundaries.add(new Boundary(5,height/2,10,height)); - - // Make a new blob - blob = new Blob(); -} - - void draw() { - background(255); - - // We must always step through time! - box2d.step(); - - // Show the blob! - blob.display(); - - // Show the boundaries! - for (Boundary wall: boundaries) { - wall.display(); - } - - -} - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Blobby/Boundary.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Blobby/Boundary.pde deleted file mode 100644 index 7b5012517..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Blobby/Boundary.pde +++ /dev/null @@ -1,54 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A fixed boundary class - -class Boundary { - - // A boundary is a simple rectangle with x,y,width,and height - float x; - float y; - float w; - float h; - - // But we also have to make a body for box2d to know about it - Body b; - - Boundary(float x_,float y_, float w_, float h_) { - x = x_; - y = y_; - w = w_; - h = h_; - - // Define the polygon - PolygonShape sd = new PolygonShape(); - // Figure out the box2d coordinates - float box2dW = box2d.scalarPixelsToWorld(w/2); - float box2dH = box2d.scalarPixelsToWorld(h/2); - // We're just a box - sd.setAsBox(box2dW, box2dH); - - - // Create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.STATIC; - bd.position.set(box2d.coordPixelsToWorld(x,y)); - b = box2d.createBody(bd); - - // Attached the shape to the body using a Fixture - b.createFixture(sd,1); - } - - // Draw the boundary, if it were at an angle we'd have to do something fancier - void display() { - fill(0); - stroke(0); - rectMode(CENTER); - rect(x,y,w,h); - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionListeningDeletionExercise/Boundary.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionListeningDeletionExercise/Boundary.pde deleted file mode 100644 index 06c5bf80d..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionListeningDeletionExercise/Boundary.pde +++ /dev/null @@ -1,56 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A fixed boundary class - -class Boundary { - - // A boundary is a simple rectangle with x,y,width,and height - float x; - float y; - float w; - float h; - - // But we also have to make a body for box2d to know about it - Body b; - - Boundary(float x_,float y_, float w_, float h_) { - x = x_; - y = y_; - w = w_; - h = h_; - - // Define the polygon - PolygonShape sd = new PolygonShape(); - // Figure out the box2d coordinates - float box2dW = box2d.scalarPixelsToWorld(w/2); - float box2dH = box2d.scalarPixelsToWorld(h/2); - // We're just a box - sd.setAsBox(box2dW, box2dH); - - - // Create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.STATIC; - bd.position.set(box2d.coordPixelsToWorld(x,y)); - b = box2d.createBody(bd); - - // Attached the shape to the body using a Fixture - b.createFixture(sd,1); - - b.setUserData(this); - } - - // Draw the boundary, if it were at an angle we'd have to do something fancier - void display() { - fill(0); - stroke(0); - rectMode(CENTER); - rect(x,y,w,h); - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionListeningDeletionExercise/CollisionListeningDeletionExercise.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionListeningDeletionExercise/CollisionListeningDeletionExercise.pde deleted file mode 100644 index b99e9108e..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionListeningDeletionExercise/CollisionListeningDeletionExercise.pde +++ /dev/null @@ -1,121 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Basic example of controlling an object with our own motion (by attaching a MouseJoint) -// Also demonstrates how to know which object was hit - -import pbox2d.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.joints.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.collision.shapes.Shape; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; -import org.jbox2d.dynamics.contacts.*; - -// A reference to our box2d world -PBox2D box2d; - -// An ArrayList of particles that will fall on the surface -ArrayList particles; - -Boundary wall; - -void setup() { - size(400, 300); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - - // Turn on collision listening! - box2d.listenForCollisions(); - - // Create the empty list - particles = new ArrayList(); - - wall = new Boundary(width/2, height-5, width, 10); -} - -void draw() { - background(255); - - if (random(1) < 0.1) { - float sz = random(4, 8); - particles.add(new Particle(random(width), 20, sz)); - } - - - // We must always step through time! - box2d.step(); - - // Look at all particles - for (int i = particles.size()-1; i >= 0; i--) { - Particle p = particles.get(i); - p.display(); - // Particles that leave the screen, we delete them - // (note they have to be deleted from both the box2d world and our list - if (p.done()) { - particles.remove(i); - } - } - - wall.display(); -} - - -// Collision event functions! -void beginContact(Contact cp) { - // Get both shapes - Fixture f1 = cp.getFixtureA(); - Fixture f2 = cp.getFixtureB(); - // Get both bodies - Body b1 = f1.getBody(); - Body b2 = f2.getBody(); - - // Get our objects that reference these bodies - Object o1 = b1.getUserData(); - Object o2 = b2.getUserData(); - - if (o1.getClass() == Particle.class && o2.getClass() == Particle.class) { - Particle p1 = (Particle) o1; - p1.delete(); - Particle p2 = (Particle) o2; - p2.delete(); - } - - if (o1.getClass() == Boundary.class) { - Particle p = (Particle) o2; - p.change(); - } - if (o2.getClass() == Boundary.class) { - Particle p = (Particle) o1; - p.change(); - } - - -} - -// Objects stop touching each other -void endContact(Contact cp) { -} - - - - - - - - - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionListeningDeletionExercise/Particle.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionListeningDeletionExercise/Particle.pde deleted file mode 100644 index 7fe629d81..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionListeningDeletionExercise/Particle.pde +++ /dev/null @@ -1,96 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// A circular particle - -class Particle { - - // We need to keep track of a Body and a radius - Body body; - float r; - - color col; - - boolean delete = false; - - Particle(float x, float y, float r_) { - r = r_; - // This function puts the particle in the Box2d world - makeBody(x, y, r); - body.setUserData(this); - col = color(175); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - void delete() { - delete = true; - } - - // Change color when hit - void change() { - col = color(255, 0, 0); - } - - // Is the particle ready for deletion? - // Is the particle ready for deletion? - boolean done() { - // Let's find the screen position of the particle - Vec2 pos = box2d.getBodyPixelCoord(body); - // Is it off the bottom of the screen? - if (pos.y > height+r*2 || delete) { - killBody(); - return true; - } - return false; - } - // - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - pushMatrix(); - translate(pos.x, pos.y); - rotate(a); - fill(col); - stroke(0); - strokeWeight(1); - ellipse(0, 0, r*2, r*2); - // Let's add a line so we can see the rotation - line(0, 0, r, 0); - popMatrix(); - } - - // Here's our function that adds the particle to the Box2D world - void makeBody(float x, float y, float r) { - // Define a body - BodyDef bd = new BodyDef(); - // Set its position - bd.position = box2d.coordPixelsToWorld(x, y); - bd.type = BodyType.DYNAMIC; - body = box2d.createBody(bd); - - // Make the body's shape a circle - CircleShape cs = new CircleShape(); - cs.m_radius = box2d.scalarPixelsToWorld(r); - - FixtureDef fd = new FixtureDef(); - fd.shape = cs; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.01; - fd.restitution = 0.3; - - // Attach fixture to body - body.createFixture(fd); - - body.setAngularVelocity(random(-10, 10)); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControl/Box.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControl/Box.pde deleted file mode 100644 index 8eab06230..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControl/Box.pde +++ /dev/null @@ -1,86 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A rectangular box - -class Box { - - // We need to keep track of a Body and a width and height - Body body; - float w; - float h; - - // Constructor - Box(float x_, float y_) { - float x = x_; - float y = y_; - w = 24; - h = 24; - // Add the box to the box2d world - makeBody(new Vec2(x, y), w, h); - body.setUserData(this); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - boolean contains(float x, float y) { - Vec2 worldPoint = box2d.coordPixelsToWorld(x, y); - Fixture f = body.getFixtureList(); - boolean inside = f.testPoint(worldPoint); - return inside; - } - - // Drawing the box - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - - rectMode(PConstants.CENTER); - pushMatrix(); - translate(pos.x, pos.y); - rotate(-a); - fill(175); - stroke(0); - rect(0, 0, w, h); - popMatrix(); - } - - // This function adds the rectangle to the box2d world - void makeBody(Vec2 center, float w_, float h_) { - // Define and create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.DYNAMIC; - bd.position.set(box2d.coordPixelsToWorld(center)); - body = box2d.createBody(bd); - - // Define a polygon (this is what we use for a rectangle) - PolygonShape sd = new PolygonShape(); - float box2dW = box2d.scalarPixelsToWorld(w_/2); - float box2dH = box2d.scalarPixelsToWorld(h_/2); - sd.setAsBox(box2dW, box2dH); - - // Define a fixture - FixtureDef fd = new FixtureDef(); - fd.shape = sd; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.3; - fd.restitution = 0.5; - - body.createFixture(fd); - //body.setMassFromShapes(); - - // Give it some initial random velocity - body.setLinearVelocity(new Vec2(random(-5, 5), random(2, 5))); - body.setAngularVelocity(random(-5, 5)); - } -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControl/CollisionsAndControl.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControl/CollisionsAndControl.pde deleted file mode 100644 index 7377f497f..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControl/CollisionsAndControl.pde +++ /dev/null @@ -1,153 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Basic example of controlling an object with our own motion (by attaching a MouseJoint) -// Also demonstrates how to know which object was hit - -import pbox2d.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.joints.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.collision.shapes.Shape; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; -import org.jbox2d.dynamics.contacts.*; - -// A reference to our box2d world -PBox2D box2d; - -// Just a single box this time -Box box; - -// An ArrayList of particles that will fall on the surface -ArrayList particles; - -// The Spring that will attach to the box from the mouse -Spring spring; - -// Perlin noise values -float xoff = 0; -float yoff = 1000; - - -void setup() { - size(400,300); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - - // Turn on collision listening! - box2d.listenForCollisions(); - - // Make the box - box = new Box(width/2,height/2); - - // Make the spring (it doesn't really get initialized until the mouse is clicked) - spring = new Spring(); - spring.bind(width/2,height/2,box); - - // Create the empty list - particles = new ArrayList(); - - -} - -void draw() { - background(255); - - if (random(1) < 0.2) { - float sz = random(4,8); - particles.add(new Particle(width/2,-20,sz)); - } - - - // We must always step through time! - box2d.step(); - - // Make an x,y coordinate out of perlin noise - float x = noise(xoff)*width; - float y = noise(yoff)*height; - xoff += 0.01; - yoff += 0.01; - - // This is tempting but will not work! - // box.body.setXForm(box2d.screenToWorld(x,y),0); - - // Instead update the spring which pulls the mouse along - if (mousePressed) { - spring.update(mouseX,mouseY); - spring.display(); - } else { - spring.update(x,y); - } - box.body.setAngularVelocity(0); - - // Look at all particles - for (int i = particles.size()-1; i >= 0; i--) { - Particle p = particles.get(i); - p.display(); - // Particles that leave the screen, we delete them - // (note they have to be deleted from both the box2d world and our list - if (p.done()) { - particles.remove(i); - } - } - - // Draw the box - box.display(); - - // Draw the spring - // spring.display(); -} - - -// Collision event functions! -void beginContact(Contact cp) { - // Get both fixtures - Fixture f1 = cp.getFixtureA(); - Fixture f2 = cp.getFixtureB(); - // Get both bodies - Body b1 = f1.getBody(); - Body b2 = f2.getBody(); - // Get our objects that reference these bodies - Object o1 = b1.getUserData(); - Object o2 = b2.getUserData(); - - // If object 1 is a Box, then object 2 must be a particle - // Note we are ignoring particle on particle collisions - if (o1.getClass() == Box.class) { - Particle p = (Particle) o2; - p.change(); - } - // If object 2 is a Box, then object 1 must be a particle - else if (o2.getClass() == Box.class) { - Particle p = (Particle) o1; - p.change(); - } -} - - -// Objects stop touching each other -void endContact(Contact cp) { -} - - - - - - - - - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControl/Particle.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControl/Particle.pde deleted file mode 100644 index d21b5f819..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControl/Particle.pde +++ /dev/null @@ -1,92 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// A circular particle - -class Particle { - - // We need to keep track of a Body and a radius - Body body; - float r; - - color col; - - - Particle(float x, float y, float r_) { - r = r_; - // This function puts the particle in the Box2d world - makeBody(x, y, r); - body.setUserData(this); - col = color(175); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - // Change color when hit - void change() { - col = color(255, 0, 0); - } - - // Is the particle ready for deletion? - boolean done() { - // Let's find the screen position of the particle - Vec2 pos = box2d.getBodyPixelCoord(body); - // Is it off the bottom of the screen? - if (pos.y > height+r*2) { - killBody(); - return true; - } - return false; - } - - - // - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - pushMatrix(); - translate(pos.x, pos.y); - rotate(a); - fill(col); - stroke(0); - strokeWeight(1); - ellipse(0, 0, r*2, r*2); - // Let's add a line so we can see the rotation - line(0, 0, r, 0); - popMatrix(); - } - - // Here's our function that adds the particle to the Box2D world - void makeBody(float x, float y, float r) { - // Define a body - BodyDef bd = new BodyDef(); - // Set its position - bd.position = box2d.coordPixelsToWorld(x, y); - bd.type = BodyType.DYNAMIC; - body = box2d.createBody(bd); - - // Make the body's shape a circle - CircleShape cs = new CircleShape(); - cs.m_radius = box2d.scalarPixelsToWorld(r); - - FixtureDef fd = new FixtureDef(); - fd.shape = cs; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.01; - fd.restitution = 0.3; - - // Attach fixture to body - body.createFixture(fd); - - body.setAngularVelocity(random(-10, 10)); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControl/Spring.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControl/Spring.pde deleted file mode 100644 index a9fcbc6c5..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControl/Spring.pde +++ /dev/null @@ -1,82 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// Class to describe the spring joint (displayed as a line) - -class Spring { - - // This is the box2d object we need to create - MouseJoint mouseJoint; - - Spring() { - // At first it doesn't exist - mouseJoint = null; - } - - // If it exists we set its target to the mouse location - void update(float x, float y) { - if (mouseJoint != null) { - // Always convert to world coordinates! - Vec2 mouseWorld = box2d.coordPixelsToWorld(x,y); - mouseJoint.setTarget(mouseWorld); - } - } - - void display() { - if (mouseJoint != null) { - // We can get the two anchor points - Vec2 v1 = new Vec2(0,0); - mouseJoint.getAnchorA(v1); - Vec2 v2 = new Vec2(0,0); - mouseJoint.getAnchorB(v2); - // Convert them to screen coordinates - v1 = box2d.coordWorldToPixels(v1); - v2 = box2d.coordWorldToPixels(v2); - // And just draw a line - stroke(0); - strokeWeight(1); - line(v1.x,v1.y,v2.x,v2.y); - } - } - - - // This is the key function where - // we attach the spring to an x,y location - // and the Box object's location - void bind(float x, float y, Box box) { - // Define the joint - MouseJointDef md = new MouseJointDef(); - - // Body A is just a fake ground body for simplicity (there isn't anything at the mouse) - md.bodyA = box2d.getGroundBody(); - // Body 2 is the box's boxy - md.bodyB = box.body; - // Get the mouse location in world coordinates - Vec2 mp = box2d.coordPixelsToWorld(x,y); - // And that's the target - md.target.set(mp); - // Some stuff about how strong and bouncy the spring should be - md.maxForce = 1000.0 * box.body.m_mass; - md.frequencyHz = 5.0; - md.dampingRatio = 0.9; - - // Wake up body! - //box.body.wakeUp(); - - // Make the joint! - mouseJoint = (MouseJoint) box2d.world.createJoint(md); - } - - void destroy() { - // We can get rid of the joint when the mouse is released - if (mouseJoint != null) { - box2d.world.destroyJoint(mouseJoint); - mouseJoint = null; - } - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/Box.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/Box.pde deleted file mode 100644 index 8eab06230..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/Box.pde +++ /dev/null @@ -1,86 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A rectangular box - -class Box { - - // We need to keep track of a Body and a width and height - Body body; - float w; - float h; - - // Constructor - Box(float x_, float y_) { - float x = x_; - float y = y_; - w = 24; - h = 24; - // Add the box to the box2d world - makeBody(new Vec2(x, y), w, h); - body.setUserData(this); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - boolean contains(float x, float y) { - Vec2 worldPoint = box2d.coordPixelsToWorld(x, y); - Fixture f = body.getFixtureList(); - boolean inside = f.testPoint(worldPoint); - return inside; - } - - // Drawing the box - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - - rectMode(PConstants.CENTER); - pushMatrix(); - translate(pos.x, pos.y); - rotate(-a); - fill(175); - stroke(0); - rect(0, 0, w, h); - popMatrix(); - } - - // This function adds the rectangle to the box2d world - void makeBody(Vec2 center, float w_, float h_) { - // Define and create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.DYNAMIC; - bd.position.set(box2d.coordPixelsToWorld(center)); - body = box2d.createBody(bd); - - // Define a polygon (this is what we use for a rectangle) - PolygonShape sd = new PolygonShape(); - float box2dW = box2d.scalarPixelsToWorld(w_/2); - float box2dH = box2d.scalarPixelsToWorld(h_/2); - sd.setAsBox(box2dW, box2dH); - - // Define a fixture - FixtureDef fd = new FixtureDef(); - fd.shape = sd; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.3; - fd.restitution = 0.5; - - body.createFixture(fd); - //body.setMassFromShapes(); - - // Give it some initial random velocity - body.setLinearVelocity(new Vec2(random(-5, 5), random(2, 5))); - body.setAngularVelocity(random(-5, 5)); - } -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/CollisionsAndControlInterface.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/CollisionsAndControlInterface.pde deleted file mode 100644 index 64c6ec3e9..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/CollisionsAndControlInterface.pde +++ /dev/null @@ -1,114 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// Basic example of controlling an object with our own motion (by attaching a MouseJoint) -// Also demonstrates how to know which object was hit - -import pbox2d.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.joints.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.collision.shapes.Shape; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; -import org.jbox2d.dynamics.contacts.*; - -// A reference to our box2d world -PBox2D box2d; - -// Just a single box this time -Box box; - -// An ArrayList of particles that will fall on the surface -ArrayList particles; - -// The Spring that will attach to the box from the mouse -Spring spring; - -// Perlin noise values -float xoff = 0; -float yoff = 1000; - - -void setup() { - size(400,300); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - - // Add a listener to listen for collisions! - box2d.world.setContactListener(new CustomListener()); - - // Make the box - box = new Box(width/2,height/2); - - // Make the spring (it doesn't really get initialized until the mouse is clicked) - spring = new Spring(); - spring.bind(width/2,height/2,box); - - // Create the empty list - particles = new ArrayList(); - - -} - -void draw() { - background(255); - - if (random(1) < 0.2) { - float sz = random(4,8); - particles.add(new Particle(width/2,-20,sz)); - } - - - // We must always step through time! - box2d.step(); - - // Make an x,y coordinate out of perlin noise - float x = noise(xoff)*width; - float y = noise(yoff)*height; - xoff += 0.01; - yoff += 0.01; - - // This is tempting but will not work! - // box.body.setXForm(box2d.screenToWorld(x,y),0); - - // Instead update the spring which pulls the mouse along - if (mousePressed) { - spring.update(mouseX,mouseY); - } else { - spring.update(x,y); - } - //box.body.setAngularVelocity(0); - - // Look at all particles - for (int i = particles.size()-1; i >= 0; i--) { - Particle p = particles.get(i); - p.display(); - // Particles that leave the screen, we delete them - // (note they have to be deleted from both the box2d world and our list - if (p.done()) { - particles.remove(i); - } - } - - // Draw the box - box.display(); - - // Draw the spring - // spring.display(); -} - - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/ContactListener.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/ContactListener.pde deleted file mode 100644 index dafe17f7e..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/ContactListener.pde +++ /dev/null @@ -1,57 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// ContactListener to listen for collisions! - -import org.jbox2d.callbacks.ContactImpulse; -import org.jbox2d.callbacks.ContactListener; -import org.jbox2d.collision.Manifold; -import org.jbox2d.dynamics.contacts.Contact; - - class CustomListener implements ContactListener { - CustomListener() { - } - - // This function is called when a new collision occurs - void beginContact(Contact cp) { - // Get both fixtures - Fixture f1 = cp.getFixtureA(); - Fixture f2 = cp.getFixtureB(); - // Get both bodies - Body b1 = f1.getBody(); - Body b2 = f2.getBody(); - // Get our objects that reference these bodies - Object o1 = b1.getUserData(); - Object o2 = b2.getUserData(); - - // If object 1 is a Box, then object 2 must be a particle - // Note we are ignoring particle on particle collisions - if (o1.getClass() == Box.class) { - Particle p = (Particle) o2; - p.change(); - } - // If object 2 is a Box, then object 1 must be a particle - else if (o2.getClass() == Box.class) { - Particle p = (Particle) o1; - p.change(); - } - } - - void endContact(Contact contact) { - // TODO Auto-generated method stub - } - - void preSolve(Contact contact, Manifold oldManifold) { - // TODO Auto-generated method stub - } - - void postSolve(Contact contact, ContactImpulse impulse) { - // TODO Auto-generated method stub - } -} - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/Particle.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/Particle.pde deleted file mode 100644 index d21b5f819..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/Particle.pde +++ /dev/null @@ -1,92 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// A circular particle - -class Particle { - - // We need to keep track of a Body and a radius - Body body; - float r; - - color col; - - - Particle(float x, float y, float r_) { - r = r_; - // This function puts the particle in the Box2d world - makeBody(x, y, r); - body.setUserData(this); - col = color(175); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - // Change color when hit - void change() { - col = color(255, 0, 0); - } - - // Is the particle ready for deletion? - boolean done() { - // Let's find the screen position of the particle - Vec2 pos = box2d.getBodyPixelCoord(body); - // Is it off the bottom of the screen? - if (pos.y > height+r*2) { - killBody(); - return true; - } - return false; - } - - - // - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - pushMatrix(); - translate(pos.x, pos.y); - rotate(a); - fill(col); - stroke(0); - strokeWeight(1); - ellipse(0, 0, r*2, r*2); - // Let's add a line so we can see the rotation - line(0, 0, r, 0); - popMatrix(); - } - - // Here's our function that adds the particle to the Box2D world - void makeBody(float x, float y, float r) { - // Define a body - BodyDef bd = new BodyDef(); - // Set its position - bd.position = box2d.coordPixelsToWorld(x, y); - bd.type = BodyType.DYNAMIC; - body = box2d.createBody(bd); - - // Make the body's shape a circle - CircleShape cs = new CircleShape(); - cs.m_radius = box2d.scalarPixelsToWorld(r); - - FixtureDef fd = new FixtureDef(); - fd.shape = cs; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.01; - fd.restitution = 0.3; - - // Attach fixture to body - body.createFixture(fd); - - body.setAngularVelocity(random(-10, 10)); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/Spring.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/Spring.pde deleted file mode 100644 index 62cac8a4b..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/CollisionsAndControlInterface/Spring.pde +++ /dev/null @@ -1,82 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// Class to describe the spring joint (displayed as a line) - -class Spring { - - // This is the box2d object we need to create - MouseJoint mouseJoint; - - Spring() { - // At first it doesn't exist - mouseJoint = null; - } - - // If it exists we set its target to the mouse location - void update(float x, float y) { - if (mouseJoint != null) { - // Always convert to world coordinates! - Vec2 mouseWorld = box2d.coordPixelsToWorld(x,y); - mouseJoint.setTarget(mouseWorld); - } - } - - void display() { - if (mouseJoint != null) { - // We can get the two anchor points - Vec2 v1 = null; - mouseJoint.getAnchorA(v1); - Vec2 v2 = null; - mouseJoint.getAnchorB(v2); - // Convert them to screen coordinates - v1 = box2d.coordWorldToPixels(v1); - v2 = box2d.coordWorldToPixels(v2); - // And just draw a line - stroke(0); - strokeWeight(1); - line(v1.x,v1.y,v2.x,v2.y); - } - } - - - // This is the key function where - // we attach the spring to an x,y location - // and the Box object's location - void bind(float x, float y, Box box) { - // Define the joint - MouseJointDef md = new MouseJointDef(); - - // Body A is just a fake ground body for simplicity (there isn't anything at the mouse) - md.bodyA = box2d.getGroundBody(); - // Body 2 is the box's boxy - md.bodyB = box.body; - // Get the mouse location in world coordinates - Vec2 mp = box2d.coordPixelsToWorld(x,y); - // And that's the target - md.target.set(mp); - // Some stuff about how strong and bouncy the spring should be - md.maxForce = 1000.0f * box.body.m_mass; - md.frequencyHz = 5.0f; - md.dampingRatio = 0.9f; - - // Wake up body! - //box.body.wakeUp(); - - // Make the joint! - mouseJoint = (MouseJoint) box2d.world.createJoint(md); - } - - void destroy() { - // We can get rid of the joint when the mouse is released - if (mouseJoint != null) { - box2d.world.destroyJoint(mouseJoint); - mouseJoint = null; - } - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceAttractMouse/Boundary.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceAttractMouse/Boundary.pde deleted file mode 100644 index 7b5012517..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceAttractMouse/Boundary.pde +++ /dev/null @@ -1,54 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A fixed boundary class - -class Boundary { - - // A boundary is a simple rectangle with x,y,width,and height - float x; - float y; - float w; - float h; - - // But we also have to make a body for box2d to know about it - Body b; - - Boundary(float x_,float y_, float w_, float h_) { - x = x_; - y = y_; - w = w_; - h = h_; - - // Define the polygon - PolygonShape sd = new PolygonShape(); - // Figure out the box2d coordinates - float box2dW = box2d.scalarPixelsToWorld(w/2); - float box2dH = box2d.scalarPixelsToWorld(h/2); - // We're just a box - sd.setAsBox(box2dW, box2dH); - - - // Create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.STATIC; - bd.position.set(box2d.coordPixelsToWorld(x,y)); - b = box2d.createBody(bd); - - // Attached the shape to the body using a Fixture - b.createFixture(sd,1); - } - - // Draw the boundary, if it were at an angle we'd have to do something fancier - void display() { - fill(0); - stroke(0); - rectMode(CENTER); - rect(x,y,w,h); - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceAttractMouse/Box.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceAttractMouse/Box.pde deleted file mode 100644 index 9319bfbc7..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceAttractMouse/Box.pde +++ /dev/null @@ -1,97 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A rectangular box -class Box { - - // We need to keep track of a Body and a width and height - Body body; - float w; - float h; - - // Constructor - Box(float x, float y) { - w = random(8,16); - h = w; - // Add the box to the box2d world - makeBody(new Vec2(x,y),w,h); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - // Is the particle ready for deletion? - boolean done() { - // Let's find the screen position of the particle - Vec2 pos = box2d.getBodyPixelCoord(body); - // Is it off the bottom of the screen? - if (pos.y > height+w*h) { - killBody(); - return true; - } - return false; - } - - void attract(float x,float y) { - // From BoxWrap2D example - Vec2 worldTarget = box2d.coordPixelsToWorld(x,y); - Vec2 bodyVec = body.getWorldCenter(); - // First find the vector going from this body to the specified point - worldTarget.subLocal(bodyVec); - // Then, scale the vector to the specified force - worldTarget.normalize(); - worldTarget.mulLocal((float) 50); - // Now apply it to the body's center of mass. - body.applyForce(worldTarget, bodyVec); - } - - - // Drawing the box - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - - rectMode(CENTER); - pushMatrix(); - translate(pos.x,pos.y); - rotate(-a); - fill(175); - stroke(0); - rect(0,0,w,h); - popMatrix(); - } - - // This function adds the rectangle to the box2d world - void makeBody(Vec2 center, float w_, float h_) { - - // Define a polygon (this is what we use for a rectangle) - PolygonShape sd = new PolygonShape(); - float box2dW = box2d.scalarPixelsToWorld(w_/2); - float box2dH = box2d.scalarPixelsToWorld(h_/2); - sd.setAsBox(box2dW, box2dH); - - // Define a fixture - FixtureDef fd = new FixtureDef(); - fd.shape = sd; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.3; - fd.restitution = 0.5; - - // Define the body and make it from the shape - BodyDef bd = new BodyDef(); - bd.type = BodyType.DYNAMIC; - bd.position.set(box2d.coordPixelsToWorld(center)); - - body = box2d.createBody(bd); - body.createFixture(fd); - } -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceAttractMouse/Ex_5_10_ApplyForceAttractMouse.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceAttractMouse/Ex_5_10_ApplyForceAttractMouse.pde deleted file mode 100644 index fbc54c32e..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceAttractMouse/Ex_5_10_ApplyForceAttractMouse.pde +++ /dev/null @@ -1,85 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Basic example of falling rectangles - -import pbox2d.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; - -// A reference to our box2d world -PBox2D box2d; - -// A list we'll use to track fixed objects -ArrayList boundaries; -// A list for all of our rectangles -ArrayList boxes; - -void setup() { - size(640,360); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - // We are setting a custom gravity - box2d.setGravity(0, -20); - - // Create ArrayLists - boxes = new ArrayList(); - boundaries = new ArrayList(); - - // Add a bunch of fixed boundaries - boundaries.add(new Boundary(width/4,height-5,width/2-50,10)); - boundaries.add(new Boundary(3*width/4,height-5,width/2-50,10)); - boundaries.add(new Boundary(width-5,height/2,10,height)); - boundaries.add(new Boundary(5,height/2,10,height)); -} - -void draw() { - background(255); - - // We must always step through time! - box2d.step(); - - // When the mouse is clicked, add a new Box object - if (random(1) < 0.1) { - Box p = new Box(random(width),10); - boxes.add(p); - } - - if (mousePressed) { - for (Box b: boxes) { - b.attract(mouseX,mouseY); - } - } - - // Display all the boundaries - for (Boundary wall: boundaries) { - wall.display(); - } - - // Display all the boxes - for (Box b: boxes) { - b.display(); - } - - // Boxes that leave the screen, we delete them - // (note they have to be deleted from both the box2d world and our list - for (int i = boxes.size()-1; i >= 0; i--) { - Box b = boxes.get(i); - if (b.done()) { - boxes.remove(i); - } - } - - fill(0); - text("Click mouse to attract boxes",20,20); -} - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceSimpleWind/Boundary.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceSimpleWind/Boundary.pde deleted file mode 100644 index 7b5012517..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceSimpleWind/Boundary.pde +++ /dev/null @@ -1,54 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A fixed boundary class - -class Boundary { - - // A boundary is a simple rectangle with x,y,width,and height - float x; - float y; - float w; - float h; - - // But we also have to make a body for box2d to know about it - Body b; - - Boundary(float x_,float y_, float w_, float h_) { - x = x_; - y = y_; - w = w_; - h = h_; - - // Define the polygon - PolygonShape sd = new PolygonShape(); - // Figure out the box2d coordinates - float box2dW = box2d.scalarPixelsToWorld(w/2); - float box2dH = box2d.scalarPixelsToWorld(h/2); - // We're just a box - sd.setAsBox(box2dW, box2dH); - - - // Create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.STATIC; - bd.position.set(box2d.coordPixelsToWorld(x,y)); - b = box2d.createBody(bd); - - // Attached the shape to the body using a Fixture - b.createFixture(sd,1); - } - - // Draw the boundary, if it were at an angle we'd have to do something fancier - void display() { - fill(0); - stroke(0); - rectMode(CENTER); - rect(x,y,w,h); - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceSimpleWind/Box.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceSimpleWind/Box.pde deleted file mode 100644 index 6dbb25b3f..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceSimpleWind/Box.pde +++ /dev/null @@ -1,88 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A rectangular box -class Box { - - // We need to keep track of a Body and a width and height - Body body; - float w; - float h; - - // Constructor - Box(float x, float y) { - w = random(8, 16); - h = w; - // Add the box to the box2d world - makeBody(new Vec2(x, y), w, h); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - // Is the particle ready for deletion? - boolean done() { - // Let's find the screen position of the particle - Vec2 pos = box2d.getBodyPixelCoord(body); - // Is it off the bottom of the screen? - if (pos.y > height+w*h) { - killBody(); - return true; - } - return false; - } - - void applyForce(Vec2 force) { - Vec2 pos = body.getWorldCenter(); - body.applyForce(force, pos); - } - - // Drawing the box - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - - rectMode(CENTER); - pushMatrix(); - translate(pos.x, pos.y); - rotate(-a); - fill(175); - stroke(0); - rect(0, 0, w, h); - popMatrix(); - } - - // This function adds the rectangle to the box2d world - void makeBody(Vec2 center, float w_, float h_) { - - // Define a polygon (this is what we use for a rectangle) - PolygonShape sd = new PolygonShape(); - float box2dW = box2d.scalarPixelsToWorld(w_/2); - float box2dH = box2d.scalarPixelsToWorld(h_/2); - sd.setAsBox(box2dW, box2dH); - - // Define a fixture - FixtureDef fd = new FixtureDef(); - fd.shape = sd; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.3; - fd.restitution = 0.2; - - // Define the body and make it from the shape - BodyDef bd = new BodyDef(); - bd.type = BodyType.DYNAMIC; - bd.position.set(box2d.coordPixelsToWorld(center)); - bd.angle = random(TWO_PI); - - body = box2d.createBody(bd); - body.createFixture(fd); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceSimpleWind/Ex_5_10_ApplyForceSimpleWind.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceSimpleWind/Ex_5_10_ApplyForceSimpleWind.pde deleted file mode 100644 index 95364b7da..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_ApplyForceSimpleWind/Ex_5_10_ApplyForceSimpleWind.pde +++ /dev/null @@ -1,86 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Basic example of falling rectangles - -import pbox2d.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; - -// A reference to our box2d world -PBox2D box2d; - -// A list we'll use to track fixed objects -ArrayList boundaries; -// A list for all of our rectangles -ArrayList boxes; - -void setup() { - size(640,360); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - // We are setting a custom gravity - box2d.setGravity(0, -20); - - // Create ArrayLists - boxes = new ArrayList(); - boundaries = new ArrayList(); - - // Add a bunch of fixed boundaries - boundaries.add(new Boundary(width/4,height-5,width/2-100,10)); - boundaries.add(new Boundary(3*width/4,height-5,width/2-100,10)); - boundaries.add(new Boundary(width-5,height/2,10,height)); - boundaries.add(new Boundary(5,height/2,10,height)); -} - -void draw() { - background(255); - - // We must always step through time! - box2d.step(); - - // When the mouse is clicked, add a new Box object - if (random(1) < 0.1) { - Box p = new Box(random(width),10); - boxes.add(p); - } - - if (mousePressed) { - for (Box b: boxes) { - Vec2 wind = new Vec2(20,0); - b.applyForce(wind); - } - } - - // Display all the boundaries - for (Boundary wall: boundaries) { - wall.display(); - } - - // Display all the boxes - for (Box b: boxes) { - b.display(); - } - - // Boxes that leave the screen, we delete them - // (note they have to be deleted from both the box2d world and our list - for (int i = boxes.size()-1; i >= 0; i--) { - Box b = boxes.get(i); - if (b.done()) { - boxes.remove(i); - } - } - - fill(0); - text("Click mouse to apply a wind force.",20,20); -} - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_AttractionApplyForce/Attractor.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_AttractionApplyForce/Attractor.pde deleted file mode 100644 index 8de891160..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_AttractionApplyForce/Attractor.pde +++ /dev/null @@ -1,70 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Showing how to use applyForce() with box2d - -// Fixed Attractor (this is redundant with Mover) - -class Attractor { - - // We need to keep track of a Body and a radius - Body body; - float r; - - Attractor(float r_, float x, float y) { - r = r_; - // Define a body - BodyDef bd = new BodyDef(); - bd.type = BodyType.STATIC; - // Set its position - bd.position = box2d.coordPixelsToWorld(x,y); - body = box2d.world.createBody(bd); - - // Make the body's shape a circle - CircleShape cs = new CircleShape(); - cs.m_radius = box2d.scalarPixelsToWorld(r); - - body.createFixture(cs,1); - - } - - - // Formula for gravitational attraction - // We are computing this in "world" coordinates - // No need to convert to pixels and back - Vec2 attract(Mover m) { - float G = 100; // Strength of force - // clone() makes us a copy - Vec2 pos = body.getWorldCenter(); - Vec2 moverPos = m.body.getWorldCenter(); - // Vector pointing from mover to attractor - Vec2 force = pos.sub(moverPos); - float distance = force.length(); - // Keep force within bounds - distance = constrain(distance,1,5); - force.normalize(); - // Note the attractor's mass is 0 because it's fixed so can't use that - float strength = (G * 1 * m.body.m_mass) / (distance * distance); // Calculate gravitional force magnitude - force.mulLocal(strength); // Get force vector --> magnitude * direction - return force; - } - - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - pushMatrix(); - translate(pos.x,pos.y); - rotate(a); - fill(175); - stroke(0); - strokeWeight(2); - ellipse(0,0,r*2,r*2); - popMatrix(); - } -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_AttractionApplyForce/Ex_5_10_AttractionApplyForce.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_AttractionApplyForce/Ex_5_10_AttractionApplyForce.pde deleted file mode 100644 index 7d7d49224..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_AttractionApplyForce/Ex_5_10_AttractionApplyForce.pde +++ /dev/null @@ -1,60 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Showing how to use applyForce() with box2d - -import pbox2d.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; - -// A reference to our box2d world -PBox2D box2d; - -// Movers, jsut like before! -Mover[] movers = new Mover[25]; - -// Attractor, just like before! -Attractor a; - -void setup() { - size(800,200); - smooth(); - - box2d = new PBox2D(this); - box2d.createWorld(); - // No global gravity force - box2d.setGravity(0,0); - - for (int i = 0; i < movers.length; i++) { - movers[i] = new Mover(random(8,16),random(width),random(height)); - } - a = new Attractor(32,width/2,height/2); -} - -void draw() { - background(255); - - // We must always step through time! - box2d.step(); - - a.display(); - - for (int i = 0; i < movers.length; i++) { - // Look, this is just like what we had before! - Vec2 force = a.attract(movers[i]); - movers[i].applyForce(force); - movers[i].display(); - } -} - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_AttractionApplyForce/Mover.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_AttractionApplyForce/Mover.pde deleted file mode 100644 index dcf446eeb..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_10_AttractionApplyForce/Mover.pde +++ /dev/null @@ -1,64 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Showing how to use applyForce() with box2d - -class Mover { - - // We need to keep track of a Body and a radius - Body body; - float r; - - Mover(float r_, float x, float y) { - r = r_; - // Define a body - BodyDef bd = new BodyDef(); - bd.type = BodyType.DYNAMIC; - - // Set its position - bd.position = box2d.coordPixelsToWorld(x,y); - body = box2d.world.createBody(bd); - - // Make the body's shape a circle - CircleShape cs = new CircleShape(); - cs.m_radius = box2d.scalarPixelsToWorld(r); - - // Define a fixture - FixtureDef fd = new FixtureDef(); - fd.shape = cs; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.3; - fd.restitution = 0.5; - - body.createFixture(fd); - - body.setLinearVelocity(new Vec2(random(-5,5),random(-5,-5))); - body.setAngularVelocity(random(-1,1)); - } - - void applyForce(Vec2 v) { - body.applyForce(v, body.getWorldCenter()); - } - - - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - pushMatrix(); - translate(pos.x,pos.y); - rotate(a); - fill(127); - stroke(0); - strokeWeight(2); - ellipse(0,0,r*2,r*2); - // Let's add a line so we can see the rotation - line(0,0,r,0); - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_NoiseChain/Ex_5_3_NoiseChain.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_NoiseChain/Ex_5_3_NoiseChain.pde deleted file mode 100644 index 708e99688..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_NoiseChain/Ex_5_3_NoiseChain.pde +++ /dev/null @@ -1,72 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// An uneven surface - -import pbox2d.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; -import org.jbox2d.dynamics.*; - -// A reference to our box2d world -PBox2D box2d; - -// An ArrayList of particles that will fall on the surface -ArrayList particles; - -// An object to store information about the uneven surface -Surface surface; - -void setup() { - size(383,200); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - // We are setting a custom gravity - box2d.setGravity(0, -20); - - // Create the empty list - particles = new ArrayList(); - // Create the surface - surface = new Surface(); -} - -void draw() { - // If the mouse is pressed, we make new particles - if (mousePressed) { - float sz = random(2,6); - particles.add(new Particle(mouseX,mouseY,sz)); - } - - // We must always step through time! - box2d.step(); - - background(255); - - // Draw the surface - surface.display(); - - // Draw all particles - for (Particle p: particles) { - p.display(); - } - - // Particles that leave the screen, we delete them - // (note they have to be deleted from both the box2d world and our list - for (int i = particles.size()-1; i >= 0; i--) { - Particle p = particles.get(i); - if (p.done()) { - particles.remove(i); - } - } -} - - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_NoiseChain/Particle.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_NoiseChain/Particle.pde deleted file mode 100644 index be9a07e7e..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_NoiseChain/Particle.pde +++ /dev/null @@ -1,90 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// A circular particle - -class Particle { - - // We need to keep track of a Body and a radius - Body body; - float r; - - Particle(float x, float y, float r_) { - r = r_; - // This function puts the particle in the Box2d world - makeBody(x,y,r); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - // Is the particle ready for deletion? - boolean done() { - // Let's find the screen position of the particle - Vec2 pos = box2d.getBodyPixelCoord(body); - // Is it off the bottom of the screen? - if (pos.y > height+r*2) { - killBody(); - return true; - } - return false; - } - - // - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - pushMatrix(); - translate(pos.x,pos.y); - rotate(-a); - fill(175); - stroke(0); - strokeWeight(1); - ellipse(0,0,r*2,r*2); - // Let's add a line so we can see the rotation - line(0,0,r,0); - popMatrix(); - } - - // Here's our function that adds the particle to the Box2D world - void makeBody(float x, float y, float r) { - // Define a body - BodyDef bd = new BodyDef(); - // Set its position - bd.position = box2d.coordPixelsToWorld(x,y); - bd.type = BodyType.DYNAMIC; - body = box2d.world.createBody(bd); - - // Make the body's shape a circle - CircleShape cs = new CircleShape(); - cs.m_radius = box2d.scalarPixelsToWorld(r); - - FixtureDef fd = new FixtureDef(); - fd.shape = cs; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.01; - fd.restitution = 0.3; - - // Attach fixture to body - body.createFixture(fd); - - // Give it a random initial velocity (and angular velocity) - body.setLinearVelocity(new Vec2(random(-10f,10f),random(5f,10f))); - body.setAngularVelocity(random(-10,10)); - } - - - - - - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_NoiseChain/Surface.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_NoiseChain/Surface.pde deleted file mode 100644 index a8d72166a..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_NoiseChain/Surface.pde +++ /dev/null @@ -1,79 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// An uneven surface boundary - -class Surface { - // We'll keep track of all of the surface points - ArrayList surface; - - - Surface() { - surface = new ArrayList(); - - // This is what box2d uses to put the surface in its world - ChainShape chain = new ChainShape(); - - // Perlin noise argument - float xoff = 0.0; - - // This has to go backwards so that the objects bounce off the top of the surface - // This "edgechain" will only work in one direction! - for (float x = width+10; x > -10; x -= 5) { - - // Doing some stuff with perlin noise to calculate a surface that points down on one side - // and up on the other - float y; - if (x > width/2) { - y = 50 + (width - x)*1.1 + map(noise(xoff),0,1,-80,80); - } - else { - y = 50 + x*1.1 + map(noise(xoff),0,1,-40,40); - } - - // Store the vertex in screen coordinates - surface.add(new Vec2(x,y)); - - // Move through perlin noise - xoff += 0.1; - - } - - // Build an array of vertices in Box2D coordinates - // from the ArrayList we made - Vec2[] vertices = new Vec2[surface.size()]; - for (int i = 0; i < vertices.length; i++) { - Vec2 edge = box2d.coordPixelsToWorld(surface.get(i)); - vertices[i] = edge; - } - - // Create the chain! - chain.createChain(vertices,vertices.length); - - // The edge chain is now attached to a body via a fixture - BodyDef bd = new BodyDef(); - bd.position.set(0.0f,0.0f); - Body body = box2d.createBody(bd); - // Shortcut, we could define a fixture if we - // want to specify frictions, restitution, etc. - body.createFixture(chain,1); - - } - - // A simple function to just draw the edge chain as a series of vertex points - void display() { - strokeWeight(2); - stroke(0); - noFill(); - beginShape(); - for (Vec2 v: surface) { - vertex(v.x,v.y); - } - endShape(); - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_SineChain/Ex_5_3_SineChain.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_SineChain/Ex_5_3_SineChain.pde deleted file mode 100644 index f96ba5619..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_SineChain/Ex_5_3_SineChain.pde +++ /dev/null @@ -1,72 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// An uneven surface - -import pbox2d.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; -import org.jbox2d.dynamics.*; - -// A reference to our box2d world -PBox2D box2d; - -// An ArrayList of particles that will fall on the surface -ArrayList particles; - -// An object to store information about the uneven surface -Surface surface; - -void setup() { - size(383,200); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - // We are setting a custom gravity - box2d.setGravity(0, -10); - - // Create the empty list - particles = new ArrayList(); - // Create the surface - surface = new Surface(); -} - -void draw() { - // If the mouse is pressed, we make new particles - if (random(1) < 0.5) { - float sz = random(2,6); - particles.add(new Particle(width/2,10,sz)); - } - - // We must always step through time! - box2d.step(); - - background(255); - - // Draw the surface - surface.display(); - - // Draw all particles - for (Particle p: particles) { - p.display(); - } - - // Particles that leave the screen, we delete them - // (note they have to be deleted from both the box2d world and our list - for (int i = particles.size()-1; i >= 0; i--) { - Particle p = particles.get(i); - if (p.done()) { - particles.remove(i); - } - } -} - - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_SineChain/Particle.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_SineChain/Particle.pde deleted file mode 100644 index 8ef8d65b2..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_SineChain/Particle.pde +++ /dev/null @@ -1,90 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A circular particle - -class Particle { - - // We need to keep track of a Body and a radius - Body body; - float r; - - Particle(float x, float y, float r_) { - r = r_; - // This function puts the particle in the Box2d world - makeBody(x,y,r); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - // Is the particle ready for deletion? - boolean done() { - // Let's find the screen position of the particle - Vec2 pos = box2d.getBodyPixelCoord(body); - // Is it off the bottom of the screen? - if (pos.y > height+r*2) { - killBody(); - return true; - } - return false; - } - - // - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - pushMatrix(); - translate(pos.x,pos.y); - rotate(-a); - fill(175); - stroke(0); - strokeWeight(1); - ellipse(0,0,r*2,r*2); - // Let's add a line so we can see the rotation - line(0,0,r,0); - popMatrix(); - } - - // Here's our function that adds the particle to the Box2D world - void makeBody(float x, float y, float r) { - // Define a body - BodyDef bd = new BodyDef(); - // Set its position - bd.position = box2d.coordPixelsToWorld(x,y); - bd.type = BodyType.DYNAMIC; - body = box2d.world.createBody(bd); - - // Make the body's shape a circle - CircleShape cs = new CircleShape(); - cs.m_radius = box2d.scalarPixelsToWorld(r); - - FixtureDef fd = new FixtureDef(); - fd.shape = cs; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.01; - fd.restitution = 0.3; - - // Attach fixture to body - body.createFixture(fd); - - // Give it a random initial velocity (and angular velocity) - body.setLinearVelocity(new Vec2(random(-10f,10f),random(5f,10f))); - body.setAngularVelocity(random(-10,10)); - } - - - - - - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_SineChain/Surface.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_SineChain/Surface.pde deleted file mode 100644 index ec00f3e54..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_3_SineChain/Surface.pde +++ /dev/null @@ -1,70 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// An uneven surface boundary - -class Surface { - // We'll keep track of all of the surface points - ArrayList surface; - - - Surface() { - surface = new ArrayList(); - - // This is what box2d uses to put the surface in its world - ChainShape chain = new ChainShape(); - - float theta = 0; - - // This has to go backwards so that the objects bounce off the top of the surface - // This "edgechain" will only work in one direction! - for (float x = width+10; x > -10; x -= 5) { - - // Doing some stuff with perlin noise to calculate a surface that points down on one side - // and up on the other - float y = map(cos(theta),-1,1,75,height-10); - theta += 0.15; - - // Store the vertex in screen coordinates - surface.add(new Vec2(x,y)); - - } - - // Build an array of vertices in Box2D coordinates - // from the ArrayList we made - Vec2[] vertices = new Vec2[surface.size()]; - for (int i = 0; i < vertices.length; i++) { - Vec2 edge = box2d.coordPixelsToWorld(surface.get(i)); - vertices[i] = edge; - } - - // Create the chain! - chain.createChain(vertices,vertices.length); - - // The edge chain is now attached to a body via a fixture - BodyDef bd = new BodyDef(); - bd.position.set(0.0f,0.0f); - Body body = box2d.createBody(bd); - // Shortcut, we could define a fixture if we - // want to specify frictions, restitution, etc. - body.createFixture(chain,1); - - } - - // A simple function to just draw the edge chain as a series of vertex points - void display() { - strokeWeight(2); - stroke(0); - noFill(); - beginShape(); - for (Vec2 v: surface) { - vertex(v.x,v.y); - } - endShape(); - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_6_Bridge/Box.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_6_Bridge/Box.pde deleted file mode 100644 index 19c610cb2..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_6_Bridge/Box.pde +++ /dev/null @@ -1,89 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// A rectangular box -class Box { - - // We need to keep track of a Body and a width and height - Body body; - float w; - float h; - - // Constructor - Box(float x, float y) { - w = random(4, 16); - h = random(4, 16); - // Add the box to the box2d world - makeBody(new Vec2(x, y), w, h); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - // Is the particle ready for deletion? - boolean done() { - // Let's find the screen position of the particle - Vec2 pos = box2d.getBodyPixelCoord(body); - // Is it off the bottom of the screen? - if (pos.y > height+w*h) { - killBody(); - return true; - } - return false; - } - - // Drawing the box - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - - rectMode(CENTER); - pushMatrix(); - translate(pos.x, pos.y); - rotate(-a); - stroke(0); - fill(127); - strokeWeight(2); - rect(0, 0, w, h); - popMatrix(); - } - - // This function adds the rectangle to the box2d world - void makeBody(Vec2 center, float w_, float h_) { - - // Define a polygon (this is what we use for a rectangle) - PolygonShape sd = new PolygonShape(); - float box2dW = box2d.scalarPixelsToWorld(w_/2); - float box2dH = box2d.scalarPixelsToWorld(h_/2); - sd.setAsBox(box2dW, box2dH); - - // Define a fixture - FixtureDef fd = new FixtureDef(); - fd.shape = sd; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.3; - fd.restitution = 0.5; - - // Define the body and make it from the shape - BodyDef bd = new BodyDef(); - bd.type = BodyType.DYNAMIC; - bd.position.set(box2d.coordPixelsToWorld(center)); - - body = box2d.createBody(bd); - body.createFixture(fd); - //body.setMassFromShapes(); - - // Give it some initial random velocity - body.setLinearVelocity(new Vec2(random(-5, 5), random(2, 5))); - body.setAngularVelocity(random(-5, 5)); - } -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_6_Bridge/Bridge.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_6_Bridge/Bridge.pde deleted file mode 100644 index 4fcf14477..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_6_Bridge/Bridge.pde +++ /dev/null @@ -1,67 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Series of Particles connected with distance joints - -class Bridge { - - // Bridge properties - float totalLength; // How long - int numPoints; // How many points - - // Our chain is a list of particles - ArrayList particles; - - // Chain constructor - Bridge(float l, int n) { - - totalLength = l; - numPoints = n; - - particles = new ArrayList(); - - float len = totalLength / numPoints; - - // Here is the real work, go through and add particles to the chain itself - for(int i=0; i < numPoints+1; i++) { - // Make a new particle - Particle p = null; - - // First and last particles are made with density of zero - if (i == 0 || i == numPoints) p = new Particle(i*len,height/4,4,true); - else p = new Particle(i*len,height/4,4,false); - particles.add(p); - - // Connect the particles with a distance joint - if (i > 0) { - DistanceJointDef djd = new DistanceJointDef(); - Particle previous = particles.get(i-1); - // Connection between previous particle and this one - djd.bodyA = previous.body; - djd.bodyB = p.body; - // Equilibrium length - djd.length = box2d.scalarPixelsToWorld(len); - // These properties affect how springy the joint is - djd.frequencyHz = 0; - djd.dampingRatio = 0; - - // Make the joint. Note we aren't storing a reference to the joint ourselves anywhere! - // We might need to someday, but for now it's ok - DistanceJoint dj = (DistanceJoint) box2d.world.createJoint(djd); - } - } - } - - // Draw the bridge - void display() { - for (Particle p: particles) { - p.display(); - } - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_6_Bridge/Ex_5_6_Bridge.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_6_Bridge/Ex_5_6_Bridge.pde deleted file mode 100644 index 4d341ed96..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_6_Bridge/Ex_5_6_Bridge.pde +++ /dev/null @@ -1,85 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Example demonstrating distance joints -// A bridge is formed by connected a series of particles with joints - -import pbox2d.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.joints.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.collision.shapes.Shape; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; -import org.jbox2d.dynamics.contacts.*; - -// A reference to our box2d world -PBox2D box2d; - -// An object to describe a Bridget (a list of particles with joint connections) -Bridge bridge; - -// A list for all of our rectangles -ArrayList boxes; - -void setup() { - size(800, 200); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - - - // Make the bridge - bridge = new Bridge(width, width/10); - - // Create ArrayLists - boxes = new ArrayList(); -} - -void draw() { - background(255); - - // We must always step through time! - box2d.step(); - - - // When the mouse is clicked, add a new Box object - if (mousePressed) { - Box p = new Box(mouseX, mouseY); - boxes.add(p); - } - - // Display all the boxes - for (Box b: boxes) { - b.display(); - } - - // Boxes that leave the screen, we delete them - // (note they have to be deleted from both the box2d world and our list - for (int i = boxes.size()-1; i >= 0; i--) { - Box b = boxes.get(i); - if (b.done()) { - boxes.remove(i); - } - } - - // Draw the windmill - bridge.display(); - - - fill(0); - //text("Click mouse to add boxes.", 10, height-10); -} - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_6_Bridge/Particle.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_6_Bridge/Particle.pde deleted file mode 100644 index e3c8b0097..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Exercise_5_6_Bridge/Particle.pde +++ /dev/null @@ -1,79 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// A circular particle - -class Particle { - - // We need to keep track of a Body and a radius - Body body; - float r; - - Particle(float x, float y, float r_, boolean fixed) { - r = r_; - - // Define a body - BodyDef bd = new BodyDef(); - if (fixed) bd.type = BodyType.STATIC; - else bd.type = BodyType.DYNAMIC; - - // Set its position - bd.position = box2d.coordPixelsToWorld(x,y); - body = box2d.world.createBody(bd); - - // Make the body's shape a circle - // Make the body's shape a circle - CircleShape cs = new CircleShape(); - cs.m_radius = box2d.scalarPixelsToWorld(r); - - FixtureDef fd = new FixtureDef(); - fd.shape = cs; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.3; - fd.restitution = 0.5; - - body.createFixture(fd); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - // Is the particle ready for deletion? - boolean done() { - // Let's find the screen position of the particle - Vec2 pos = box2d.getBodyPixelCoord(body); - // Is it off the bottom of the screen? - if (pos.y > height+r*2) { - killBody(); - return true; - } - return false; - } - - // - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - pushMatrix(); - translate(pos.x,pos.y); - rotate(a); - stroke(0); - fill(127); - strokeWeight(2); - ellipse(0,0,r*2,r*2); - // Let's add a line so we can see the rotation - line(0,0,r,0); - popMatrix(); - } - - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/KinematicTest/Box.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/KinematicTest/Box.pde deleted file mode 100644 index 02d085bac..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/KinematicTest/Box.pde +++ /dev/null @@ -1,103 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A rectangular box - -class Box { - - // We need to keep track of a Body and a width and height - Body body; - float w; - float h; - - boolean dragged = false; - - // Constructor - Box(float x_, float y_) { - float x = x_; - float y = y_; - w = 24; - h = 24; - // Add the box to the box2d world - makeBody(new Vec2(x,y),w,h); - body.setUserData(this); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - boolean contains(float x, float y) { - Vec2 worldPoint = box2d.coordPixelsToWorld(x, y); - Fixture f = body.getFixtureList(); - boolean inside = f.testPoint(worldPoint); - return inside; - } - - void setAngularVelocity(float a) { - body.setAngularVelocity(a); - } - void setVelocity(Vec2 v) { - body.setLinearVelocity(v); - } - - void setLocation(float x, float y) { - Vec2 pos = body.getWorldCenter(); - Vec2 target = box2d.coordPixelsToWorld(x,y); - Vec2 diff = new Vec2(target.x-pos.x,target.y-pos.y); - diff.mulLocal(50); - setVelocity(diff); - setAngularVelocity(0); - } - - // Drawing the box - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - - rectMode(PConstants.CENTER); - pushMatrix(); - translate(pos.x,pos.y); - rotate(a); - fill(175); - stroke(0); - rect(0,0,w,h); - popMatrix(); - } - - - // This function adds the rectangle to the box2d world - void makeBody(Vec2 center, float w_, float h_) { - // Define and create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.KINEMATIC; - bd.position.set(box2d.coordPixelsToWorld(center)); - bd.fixedRotation = true; - body = box2d.createBody(bd); - - // Define a polygon (this is what we use for a rectangle) - PolygonShape ps = new PolygonShape(); - float box2dW = box2d.scalarPixelsToWorld(w_/2); - float box2dH = box2d.scalarPixelsToWorld(h_/2); - ps.setAsBox(box2dW, box2dH); - - // Define a fixture - FixtureDef fd = new FixtureDef(); - fd.shape = ps; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.3; - fd.restitution = 0.5; - - body.createFixture(fd); - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/KinematicTest/KinematicTest.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/KinematicTest/KinematicTest.pde deleted file mode 100644 index 15f86aca3..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/KinematicTest/KinematicTest.pde +++ /dev/null @@ -1,144 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Basic example of controlling an object with our own motion (by attaching a MouseJoint) -// Also demonstrates how to know which object was hit - -import pbox2d.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.joints.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.collision.shapes.Shape; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; -import org.jbox2d.dynamics.contacts.*; - -// A reference to our box2d world -PBox2D box2d; - -// Just a single box this time -Box box; - -// An ArrayList of particles that will fall on the surface -ArrayList particles; - -// Perlin noise values -float xoff = 0; -float yoff = 1000; - - -void setup() { - size(640,360); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - - // Turn on collision listening! - box2d.listenForCollisions(); - - // Make the box - box = new Box(width/2,height/2); - - // Create the empty list - particles = new ArrayList(); - - -} - -void draw() { - background(255); - - if (random(1) < 0.2) { - float sz = random(4,8); - particles.add(new Particle(width/2,-20,sz)); - } - - - // We must always step through time! - box2d.step(); - - // Make an x,y coordinate out of perlin noise - float x = noise(xoff)*width; - float y = noise(yoff)*height; - xoff += 0.01; - yoff += 0.01; - - // This is tempting but will not work! - // box.body.setXForm(box2d.screenToWorld(x,y),0); - - // Instead update the spring which pulls the mouse along - if (mousePressed) { - box.setLocation(mouseX,mouseY); - } else { - //box.setLocation(x,y); - } - - // Look at all particles - for (int i = particles.size()-1; i >= 0; i--) { - Particle p = particles.get(i); - p.display(); - // Particles that leave the screen, we delete them - // (note they have to be deleted from both the box2d world and our list - if (p.done()) { - particles.remove(i); - } - } - - // Draw the box - box.display(); - - // Draw the spring - // spring.display(); -} - - -// Collision event functions! -void beginContact(Contact cp) { - // Get both fixtures - Fixture f1 = cp.getFixtureA(); - Fixture f2 = cp.getFixtureB(); - // Get both bodies - Body b1 = f1.getBody(); - Body b2 = f2.getBody(); - // Get our objects that reference these bodies - Object o1 = b1.getUserData(); - Object o2 = b2.getUserData(); - - // If object 1 is a Box, then object 2 must be a particle - // Note we are ignoring particle on particle collisions - if (o1.getClass() == Box.class) { - Particle p = (Particle) o2; - p.change(); - } - // If object 2 is a Box, then object 1 must be a particle - else if (o2.getClass() == Box.class) { - Particle p = (Particle) o1; - p.change(); - } -} - - -// Objects stop touching each other -void endContact(Contact cp) { -} - - - - - - - - - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/KinematicTest/Particle.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/KinematicTest/Particle.pde deleted file mode 100644 index 12c50f772..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/KinematicTest/Particle.pde +++ /dev/null @@ -1,93 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// A circular particle - -class Particle { - - // We need to keep track of a Body and a radius - Body body; - float r; - - color col; - - - Particle(float x, float y, float r_) { - r = r_; - // This function puts the particle in the Box2d world - makeBody(x, y, r); - body.setUserData(this); - col = color(175); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - // Change color when hit - void change() { - col = color(255, 0, 0); - } - - // Is the particle ready for deletion? - boolean done() { - // Let's find the screen position of the particle - Vec2 pos = box2d.getBodyPixelCoord(body); - // Is it off the bottom of the screen? - if (pos.y > height+r*2) { - killBody(); - return true; - } - return false; - } - - - // - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - pushMatrix(); - translate(pos.x, pos.y); - rotate(a); - fill(col); - stroke(0); - strokeWeight(1); - ellipse(0, 0, r*2, r*2); - // Let's add a line so we can see the rotation - line(0, 0, r, 0); - popMatrix(); - } - - // Here's our function that adds the particle to the Box2D world - void makeBody(float x, float y, float r) { - // Define a body - BodyDef bd = new BodyDef(); - // Set its position - bd.position = box2d.coordPixelsToWorld(x, y); - bd.type = BodyType.DYNAMIC; - - body = box2d.createBody(bd); - - // Make the body's shape a circle - CircleShape cs = new CircleShape(); - cs.m_radius = box2d.scalarPixelsToWorld(r); - - FixtureDef fd = new FixtureDef(); - fd.shape = cs; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.01; - fd.restitution = 0.3; - - // Attach fixture to body - body.createFixture(fd); - - body.setAngularVelocity(random(-10, 10)); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Liquidy/Boundary.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Liquidy/Boundary.pde deleted file mode 100644 index d3ff672da..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Liquidy/Boundary.pde +++ /dev/null @@ -1,62 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// A fixed boundary class (now incorporates angle) - -class Boundary { - - // A boundary is a simple rectangle with x,y,width,and height - float x; - float y; - float w; - float h; - // But we also have to make a body for box2d to know about it - Body b; - - Boundary(float x_,float y_, float w_, float h_, float a) { - x = x_; - y = y_; - w = w_; - h = h_; - - // Define the polygon - PolygonShape sd = new PolygonShape(); - // Figure out the box2d coordinates - float box2dW = box2d.scalarPixelsToWorld(w/2); - float box2dH = box2d.scalarPixelsToWorld(h/2); - // We're just a box - sd.setAsBox(box2dW, box2dH); - - - // Create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.STATIC; - bd.angle = a; - bd.position.set(box2d.coordPixelsToWorld(x,y)); - b = box2d.createBody(bd); - - // Attached the shape to the body using a Fixture - b.createFixture(sd,1); - } - - // Draw the boundary, if it were at an angle we'd have to do something fancier - void display() { - noFill(); - stroke(0); - strokeWeight(1); - rectMode(CENTER); - - float a = b.getAngle(); - - pushMatrix(); - translate(x,y); - rotate(-a); - rect(0,0,w,h); - popMatrix(); - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Liquidy/Liquidy.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Liquidy/Liquidy.pde deleted file mode 100644 index 73e61f25c..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Liquidy/Liquidy.pde +++ /dev/null @@ -1,74 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Box2D particle system example - -import pbox2d.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; - - - -// A reference to our box2d world -PBox2D box2d; - -// A list we'll use to track fixed objects -ArrayList boundaries; - -// A list for all particle systems -ArrayList systems; - -void setup() { - size(400,300); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - - // We are setting a custom gravity - box2d.setGravity(0, -20); - - // Create ArrayLists - systems = new ArrayList(); - boundaries = new ArrayList(); - - // Add a bunch of fixed boundaries - boundaries.add(new Boundary(50,100,300,5,-0.3)); - boundaries.add(new Boundary(250,175,300,5,0.5)); - -} - -void draw() { - background(255); - - // We must always step through time! - box2d.step(); - - // Run all the particle systems - for (ParticleSystem system: systems) { - system.run(); - - int n = (int) random(0,2); - system.addParticles(n); - } - - // Display all the boundaries - for (Boundary wall: boundaries) { - wall.display(); - } -} - - -void mousePressed() { - // Add a new Particle System whenever the mouse is clicked - systems.add(new ParticleSystem(0, new PVector(mouseX,mouseY))); -} - - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Liquidy/Particle.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Liquidy/Particle.pde deleted file mode 100644 index 145b22276..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Liquidy/Particle.pde +++ /dev/null @@ -1,99 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A Particle - -class Particle { - - // We need to keep track of a Body - Body body; - - PVector[] trail; - - // Constructor - Particle(float x_, float y_) { - float x = x_; - float y = y_; - trail = new PVector[6]; - for (int i = 0; i < trail.length; i++) { - trail[i] = new PVector(x, y); - } - - // Add the box to the box2d world - // Here's a little trick, let's make a tiny tiny radius - // This way we have collisions, but they don't overwhelm the system - makeBody(new Vec2(x, y), 0.2f); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - // Is the particle ready for deletion? - boolean done() { - // Let's find the screen position of the particle - Vec2 pos = box2d.getBodyPixelCoord(body); - // Is it off the bottom of the screen? - if (pos.y > height+20) { - killBody(); - return true; - } - return false; - } - - // Drawing the box - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - - // Keep track of a history of screen positions in an array - for (int i = 0; i < trail.length-1; i++) { - trail[i] = trail[i+1]; - } - trail[trail.length-1] = new PVector(pos.x, pos.y); - - // Draw particle as a trail - beginShape(); - noFill(); - strokeWeight(2); - stroke(0, 150); - for (int i = 0; i < trail.length; i++) { - vertex(trail[i].x, trail[i].y); - } - endShape(); - } - - // This function adds the rectangle to the box2d world - void makeBody(Vec2 center, float r) { - // Define and create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.DYNAMIC; - - bd.position.set(box2d.coordPixelsToWorld(center)); - body = box2d.createBody(bd); - - // Give it some initial random velocity - body.setLinearVelocity(new Vec2(random(-1, 1), random(-1, 1))); - - // Make the body's shape a circle - CircleShape cs = new CircleShape(); - cs.m_radius = box2d.scalarPixelsToWorld(r); - - FixtureDef fd = new FixtureDef(); - fd.shape = cs; - - fd.density = 1; - fd.friction = 0; // Slippery when wet! - fd.restitution = 0.5; - - // We could use this if we want to turn collisions off - //cd.filter.groupIndex = -10; - - // Attach fixture to body - body.createFixture(fd); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Liquidy/ParticleSystem.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Liquidy/ParticleSystem.pde deleted file mode 100644 index 9c232f914..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/Liquidy/ParticleSystem.pde +++ /dev/null @@ -1,59 +0,0 @@ -// Box2D Particle System -// -// Spring 2010 - -// A class to describe a group of Particles -// An ArrayList is used to manage the list of Particles - -class ParticleSystem { - - ArrayList particles; // An ArrayList for all the particles - PVector origin; // An origin point for where particles are birthed - - ParticleSystem(int num, PVector v) { - particles = new ArrayList(); // Initialize the ArrayList - origin = v.get(); // Store the origin point - - for (int i = 0; i < num; i++) { - particles.add(new Particle(origin.x,origin.y)); // Add "num" amount of particles to the ArrayList - } - } - - void run() { - // Display all the particles - for (Particle p: particles) { - p.display(); - } - - // Particles that leave the screen, we delete them - // (note they have to be deleted from both the box2d world and our list - for (int i = particles.size()-1; i >= 0; i--) { - Particle p = particles.get(i); - if (p.done()) { - particles.remove(i); - } - } - } - - void addParticles(int n) { - for (int i = 0; i < n; i++) { - particles.add(new Particle(origin.x,origin.y)); - } - } - - // A method to test if the particle system still has particles - boolean dead() { - if (particles.isEmpty()) { - return true; - } - else { - return false; - } - } - -} - - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/MouseKinematic/Boundary.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/MouseKinematic/Boundary.pde deleted file mode 100644 index d3ff672da..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/MouseKinematic/Boundary.pde +++ /dev/null @@ -1,62 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// A fixed boundary class (now incorporates angle) - -class Boundary { - - // A boundary is a simple rectangle with x,y,width,and height - float x; - float y; - float w; - float h; - // But we also have to make a body for box2d to know about it - Body b; - - Boundary(float x_,float y_, float w_, float h_, float a) { - x = x_; - y = y_; - w = w_; - h = h_; - - // Define the polygon - PolygonShape sd = new PolygonShape(); - // Figure out the box2d coordinates - float box2dW = box2d.scalarPixelsToWorld(w/2); - float box2dH = box2d.scalarPixelsToWorld(h/2); - // We're just a box - sd.setAsBox(box2dW, box2dH); - - - // Create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.STATIC; - bd.angle = a; - bd.position.set(box2d.coordPixelsToWorld(x,y)); - b = box2d.createBody(bd); - - // Attached the shape to the body using a Fixture - b.createFixture(sd,1); - } - - // Draw the boundary, if it were at an angle we'd have to do something fancier - void display() { - noFill(); - stroke(0); - strokeWeight(1); - rectMode(CENTER); - - float a = b.getAngle(); - - pushMatrix(); - translate(x,y); - rotate(-a); - rect(0,0,w,h); - popMatrix(); - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/MouseKinematic/Box.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/MouseKinematic/Box.pde deleted file mode 100644 index 27682e42b..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/MouseKinematic/Box.pde +++ /dev/null @@ -1,106 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// A rectangular box - -class Box { - - // We need to keep track of a Body and a width and height - Body body; - float w; - float h; - - boolean dragged = false; - - // Constructor - Box(float x_, float y_) { - float x = x_; - float y = y_; - w = 24; - h = 24; - // Add the box to the box2d world - makeBody(new Vec2(x,y),w,h); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - boolean contains(float x, float y) { - Vec2 worldPoint = box2d.coordPixelsToWorld(x, y); - Fixture f = body.getFixtureList(); - boolean inside = f.testPoint(worldPoint); - return inside; - } - - void setAngularVelocity(float a) { - body.setAngularVelocity(a); - } - void setVelocity(Vec2 v) { - body.setLinearVelocity(v); - } - - void setLocation(float x, float y) { - Vec2 pos = body.getWorldCenter(); - Vec2 target = box2d.coordPixelsToWorld(x,y); - Vec2 diff = target.sub(pos); - diff.mulLocal(50); - setVelocity(diff); - setAngularVelocity(0); - } - - // Drawing the box - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - - rectMode(PConstants.CENTER); - pushMatrix(); - translate(pos.x,pos.y); - rotate(a); - fill(175); - stroke(0); - rect(0,0,w,h); - popMatrix(); - } - - - // This function adds the rectangle to the box2d world - void makeBody(Vec2 center, float w_, float h_) { - // Define and create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.KINEMATIC; - bd.position.set(box2d.coordPixelsToWorld(center)); - body = box2d.createBody(bd); - - // Define a polygon (this is what we use for a rectangle) - PolygonShape sd = new PolygonShape(); - float box2dW = box2d.scalarPixelsToWorld(w_/2); - float box2dH = box2d.scalarPixelsToWorld(h_/2); - sd.setAsBox(box2dW, box2dH); - - // Define a fixture - FixtureDef fd = new FixtureDef(); - fd.shape = sd; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.3; - fd.restitution = 0.5; - - body.createFixture(fd); - //body.setMassFromShapes(); - - // Give it some initial random velocity - body.setLinearVelocity(new Vec2(random(-5, 5), random(2, 5))); - body.setAngularVelocity(random(-5, 5)); - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/MouseKinematic/MouseKinematic.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/MouseKinematic/MouseKinematic.pde deleted file mode 100644 index cad1269d7..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/MouseKinematic/MouseKinematic.pde +++ /dev/null @@ -1,78 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Basic example of controlling an object with the mouse (by attaching a spring) - -import pbox2d.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.joints.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.collision.shapes.Shape; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; - -// A reference to our box2d world -PBox2D box2d; - -// A list we'll use to track fixed objects -ArrayList boundaries; - -// Just a single box this time -Box box; - -void setup() { - size(640,360); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - - // Make the box - box = new Box(width/2,height/2); - - // Add a bunch of fixed boundaries - boundaries = new ArrayList(); - boundaries.add(new Boundary(width/2,height-5,width,10,0)); - boundaries.add(new Boundary(width/2,5,width,10,0)); - boundaries.add(new Boundary(width-5,height/2,10,height,0)); - boundaries.add(new Boundary(5,height/2,10,height,0)); -} - - -void draw() { - background(255); - - // We must always step through time! - - //if (box.dragged) { - box.setLocation(mouseX,mouseY); - //} - - box2d.step(); - - // Draw the boundaries - for (Boundary wall : boundaries) { - wall.display(); - } - - // Draw the box - box.display(); - - -} - -void mousePressed() { - if (box.contains(mouseX,mouseY)) { - box.dragged = true; - } -} - -void mouseReleased() { - box.dragged = false; -} - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_1_box2d_exercise/Box.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_1_box2d_exercise/Box.pde deleted file mode 100644 index 3ffd2de0f..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_1_box2d_exercise/Box.pde +++ /dev/null @@ -1,23 +0,0 @@ -// A rectangular box -class Box { - - float x,y; - float w,h; - - // Constructor - Box(float x_, float y_) { - x = x_; - y = y_; - w = 16; - h = 16; - } - - // Drawing the box - void display() { - fill(127); - stroke(0); - strokeWeight(2); - rectMode(CENTER); - rect(x,y,w,h); - } -} diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_1_box2d_exercise/_5_1_box2d_exercise.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_1_box2d_exercise/_5_1_box2d_exercise.pde deleted file mode 100644 index 2f5ddc73b..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_1_box2d_exercise/_5_1_box2d_exercise.pde +++ /dev/null @@ -1,24 +0,0 @@ -// A list for all of our rectangles -ArrayList boxes; - -void setup() { - size(800,200); - smooth(); - // Create ArrayLists - boxes = new ArrayList(); -} - -void draw() { - background(255); - - // When the mouse is clicked, add a new Box object - if (mousePressed) { - Box p = new Box(mouseX,mouseY); - boxes.add(p); - } - - // Display all the boxes - for (Box b: boxes) { - b.display(); - } -} diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_1_box2d_exercise_solved/Box.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_1_box2d_exercise_solved/Box.pde deleted file mode 100644 index 8eff285ae..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_1_box2d_exercise_solved/Box.pde +++ /dev/null @@ -1,55 +0,0 @@ -// A rectangular box -class Box { - // Instead of any of the usual variables, we will store a reference to a Box2D Body - Body body; - - float w,h; - - Box(float x, float y) { - w = 16; - h = 16; - - // Build Body - BodyDef bd = new BodyDef(); - bd.type = BodyType.DYNAMIC; - bd.position.set(box2d.coordPixelsToWorld(x,y)); - body = box2d.createBody(bd); - - - // Define a polygon (this is what we use for a rectangle) - PolygonShape ps = new PolygonShape(); - float box2dW = box2d.scalarPixelsToWorld(w/2); - float box2dH = box2d.scalarPixelsToWorld(h/2); // Box2D considers the width and height of a - ps.setAsBox(box2dW, box2dH); // rectangle to be the distance from the - // center to the edge (so half of what we - // normally think of as width or height.) - // Define a fixture - FixtureDef fd = new FixtureDef(); - fd.shape = ps; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.3; - fd.restitution = 0.5; - - // Attach Fixture to Body - body.createFixture(fd); - } - - void display() { - // We need the Body’s location and angle - Vec2 pos = box2d.getBodyPixelCoord(body); - float a = body.getAngle(); - - pushMatrix(); - translate(pos.x,pos.y); // Using the Vec2 position and float angle to - rotate(-a); // translate and rotate the rectangle - fill(127); - stroke(0); - strokeWeight(2); - rectMode(CENTER); - rect(0,0,w,h); - popMatrix(); - } - -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_1_box2d_exercise_solved/_5_1_box2d_exercise_solved.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_1_box2d_exercise_solved/_5_1_box2d_exercise_solved.pde deleted file mode 100644 index 34b4a8acd..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_1_box2d_exercise_solved/_5_1_box2d_exercise_solved.pde +++ /dev/null @@ -1,37 +0,0 @@ -import pbox2d.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; - -// A list for all of our rectangles -ArrayList boxes; - -PBox2D box2d; - -void setup() { - size(800, 200); - smooth(); - // Initialize and create the Box2D world - box2d = new PBox2D(this); - box2d.createWorld(); - - // Create ArrayLists - boxes = new ArrayList(); -} - -void draw() { - background(255); - - // We must always step through time! - box2d.step(); - - // When the mouse is clicked, add a new Box object - Box p = new Box(mouseX, mouseY); - boxes.add(p); - - // Display all the boxes - for (Box b: boxes) { - b.display(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_2_Boxes/Boundary.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_2_Boxes/Boundary.pde deleted file mode 100644 index d180aa86d..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_2_Boxes/Boundary.pde +++ /dev/null @@ -1,54 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A fixed boundary class - -class Boundary { - - // A boundary is a simple rectangle with x,y,width,and height - float x; - float y; - float w; - float h; - - // But we also have to make a body for box2d to know about it - Body b; - - Boundary(float x_,float y_, float w_, float h_) { - x = x_; - y = y_; - w = w_; - h = h_; - - // Define the polygon - PolygonShape ps = new PolygonShape(); - // Figure out the box2d coordinates - float box2dW = box2d.scalarPixelsToWorld(w/2); - float box2dH = box2d.scalarPixelsToWorld(h/2); - // We're just a box - ps.setAsBox(box2dW, box2dH); - - - // Create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.STATIC; - bd.position.set(box2d.coordPixelsToWorld(x,y)); - b = box2d.createBody(bd); - - // Attached the shape to the body using a Fixture - b.createFixture(ps,1); - } - - // Draw the boundary, if it were at an angle we'd have to do something fancier - void display() { - fill(0); - stroke(0); - rectMode(CENTER); - rect(x,y,w,h); - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_2_Boxes/Box.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_2_Boxes/Box.pde deleted file mode 100644 index 5f76a87fa..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_2_Boxes/Box.pde +++ /dev/null @@ -1,88 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// A rectangular box -class Box { - - // We need to keep track of a Body and a width and height - Body body; - float w; - float h; - - // Constructor - Box(float x, float y) { - w = random(4, 16); - h = random(4, 16); - // Add the box to the box2d world - makeBody(new Vec2(x, y), w, h); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - // Is the particle ready for deletion? - boolean done() { - // Let's find the screen position of the particle - Vec2 pos = box2d.getBodyPixelCoord(body); - // Is it off the bottom of the screen? - if (pos.y > height+w*h) { - killBody(); - return true; - } - return false; - } - - // Drawing the box - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - - rectMode(CENTER); - pushMatrix(); - translate(pos.x, pos.y); - rotate(-a); - fill(127); - stroke(0); - strokeWeight(2); - rect(0, 0, w, h); - popMatrix(); - } - - // This function adds the rectangle to the box2d world - void makeBody(Vec2 center, float w_, float h_) { - - // Define a polygon (this is what we use for a rectangle) - PolygonShape sd = new PolygonShape(); - float box2dW = box2d.scalarPixelsToWorld(w_/2); - float box2dH = box2d.scalarPixelsToWorld(h_/2); - sd.setAsBox(box2dW, box2dH); - - // Define a fixture - FixtureDef fd = new FixtureDef(); - fd.shape = sd; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.3; - fd.restitution = 0.5; - - // Define the body and make it from the shape - BodyDef bd = new BodyDef(); - bd.type = BodyType.DYNAMIC; - bd.position.set(box2d.coordPixelsToWorld(center)); - - body = box2d.createBody(bd); - body.createFixture(fd); - - // Give it some initial random velocity - body.setLinearVelocity(new Vec2(random(-5, 5), random(2, 5))); - body.setAngularVelocity(random(-5, 5)); - } -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_2_Boxes/_5_2_Boxes.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_2_Boxes/_5_2_Boxes.pde deleted file mode 100644 index 7a80fac21..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_2_Boxes/_5_2_Boxes.pde +++ /dev/null @@ -1,74 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Basic example of falling rectangles - -import pbox2d.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; - -// A reference to our box2d world -PBox2D box2d; - -// A list we'll use to track fixed objects -ArrayList boundaries; -// A list for all of our rectangles -ArrayList boxes; - -void setup() { - size(800,200); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - // We are setting a custom gravity - box2d.setGravity(0, -10); - - // Create ArrayLists - boxes = new ArrayList(); - boundaries = new ArrayList(); - - // Add a bunch of fixed boundaries - boundaries.add(new Boundary(width/4,height-5,width/2-50,10)); - boundaries.add(new Boundary(3*width/4,height-50,width/2-50,10)); -} - -void draw() { - background(255); - - // We must always step through time! - box2d.step(); - - // Boxes fall from the top every so often - if (random(1) < 0.2) { - Box p = new Box(width/2,30); - boxes.add(p); - } - - // Display all the boundaries - for (Boundary wall: boundaries) { - wall.display(); - } - - // Display all the boxes - for (Box b: boxes) { - b.display(); - } - - // Boxes that leave the screen, we delete them - // (note they have to be deleted from both the box2d world and our list - for (int i = boxes.size()-1; i >= 0; i--) { - Box b = boxes.get(i); - if (b.done()) { - boxes.remove(i); - } - } -} - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_3_ChainShape_Simple/Particle.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_3_ChainShape_Simple/Particle.pde deleted file mode 100644 index bfd3acdf5..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_3_ChainShape_Simple/Particle.pde +++ /dev/null @@ -1,90 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A circular particle - -class Particle { - - // We need to keep track of a Body and a radius - Body body; - float r; - - Particle(float x, float y, float r_) { - r = r_; - // This function puts the particle in the Box2d world - makeBody(x,y,r); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - // Is the particle ready for deletion? - boolean done() { - // Let's find the screen position of the particle - Vec2 pos = box2d.getBodyPixelCoord(body); - // Is it off the bottom of the screen? - if (pos.y > height+r*2) { - killBody(); - return true; - } - return false; - } - - // - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - pushMatrix(); - translate(pos.x,pos.y); - rotate(-a); - fill(127); - stroke(0); - strokeWeight(2); - ellipse(0,0,r*2,r*2); - // Let's add a line so we can see the rotation - line(0,0,r,0); - popMatrix(); - } - - // Here's our function that adds the particle to the Box2D world - void makeBody(float x, float y, float r) { - // Define a body - BodyDef bd = new BodyDef(); - // Set its position - bd.position = box2d.coordPixelsToWorld(x,y); - bd.type = BodyType.DYNAMIC; - body = box2d.world.createBody(bd); - - // Make the body's shape a circle - CircleShape cs = new CircleShape(); - cs.m_radius = box2d.scalarPixelsToWorld(r); - - FixtureDef fd = new FixtureDef(); - fd.shape = cs; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.01; - fd.restitution = 0.3; - - // Attach fixture to body - body.createFixture(fd); - - // Give it a random initial velocity (and angular velocity) - body.setLinearVelocity(new Vec2(random(-10f,10f),random(5f,10f))); - body.setAngularVelocity(random(-10,10)); - } - - - - - - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_3_ChainShape_Simple/Surface.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_3_ChainShape_Simple/Surface.pde deleted file mode 100644 index 13e19576b..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_3_ChainShape_Simple/Surface.pde +++ /dev/null @@ -1,53 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// An uneven surface boundary - -class Surface { - // We'll keep track of all of the surface points - ArrayList surface; - - - Surface() { - surface = new ArrayList(); - // Here we keep track of the screen coordinates of the chain - surface.add(new Vec2(0, height/2)); - //surface.add(new Vec2(width/2, height/2+50)); - surface.add(new Vec2(width, height/2)); - - // This is what box2d uses to put the surface in its world - ChainShape chain = new ChainShape(); - - // We can add 3 vertices by making an array of 3 Vec2 objects - Vec2[] vertices = new Vec2[surface.size()]; - for (int i = 0; i < vertices.length; i++) { - vertices[i] = box2d.coordPixelsToWorld(surface.get(i)); - } - - chain.createChain(vertices, vertices.length); - - // The edge chain is now a body! - BodyDef bd = new BodyDef(); - Body body = box2d.world.createBody(bd); - // Shortcut, we could define a fixture if we - // want to specify frictions, restitution, etc. - body.createFixture(chain, 1); - } - - // A simple function to just draw the edge chain as a series of vertex points - void display() { - strokeWeight(1); - stroke(0); - fill(0); - beginShape(); - for (Vec2 v: surface) { - vertex(v.x, v.y); - } - vertex(width, height); - vertex(0, height); - endShape(CLOSE); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_3_ChainShape_Simple/_5_3_ChainShape_Simple.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_3_ChainShape_Simple/_5_3_ChainShape_Simple.pde deleted file mode 100644 index 899555fab..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_3_ChainShape_Simple/_5_3_ChainShape_Simple.pde +++ /dev/null @@ -1,72 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// An uneven surface - -import pbox2d.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; -import org.jbox2d.dynamics.*; - -// A reference to our box2d world -PBox2D box2d; - -// An ArrayList of particles that will fall on the surface -ArrayList particles; - -// An object to store information about the uneven surface -Surface surface; - -void setup() { - size(800,200); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - // We are setting a custom gravity - box2d.setGravity(0, -10); - - // Create the empty list - particles = new ArrayList(); - // Create the surface - surface = new Surface(); -} - -void draw() { - // If the mouse is pressed, we make new particles - if (random(1) < 0.5) { - float sz = random(4,8); - particles.add(new Particle(width/2,10,sz)); - } - - // We must always step through time! - box2d.step(); - - background(255); - - // Draw the surface - surface.display(); - - // Draw all particles - for (Particle p: particles) { - p.display(); - } - - // Particles that leave the screen, we delete them - // (note they have to be deleted from both the box2d world and our list - for (int i = particles.size()-1; i >= 0; i--) { - Particle p = particles.get(i); - if (p.done()) { - particles.remove(i); - } - } -} - - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_4_Polygons/Boundary.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_4_Polygons/Boundary.pde deleted file mode 100644 index 1a35aca9c..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_4_Polygons/Boundary.pde +++ /dev/null @@ -1,60 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A fixed boundary class (now incorporates angle) - -class Boundary { - - // A boundary is a simple rectangle with x,y,width,and height - float x; - float y; - float w; - float h; - // But we also have to make a body for box2d to know about it - Body b; - - Boundary(float x_,float y_, float w_, float h_, float a) { - x = x_; - y = y_; - w = w_; - h = h_; - - // Define the polygon - PolygonShape sd = new PolygonShape(); - // Figure out the box2d coordinates - float box2dW = box2d.scalarPixelsToWorld(w/2); - float box2dH = box2d.scalarPixelsToWorld(h/2); - // We're just a box - sd.setAsBox(box2dW, box2dH); - - - // Create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.STATIC; - bd.angle = a; - bd.position.set(box2d.coordPixelsToWorld(x,y)); - b = box2d.createBody(bd); - - // Attached the shape to the body using a Fixture - b.createFixture(sd,1); - } - - // Draw the boundary, it doesn't move so we don't have to ask the Body for location - void display() { - fill(0); - stroke(0); - strokeWeight(1); - rectMode(CENTER); - float a = b.getAngle(); - pushMatrix(); - translate(x,y); - rotate(-a); - rect(0,0,w,h); - popMatrix(); - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_4_Polygons/CustomShape.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_4_Polygons/CustomShape.pde deleted file mode 100644 index fcd1cb5b0..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_4_Polygons/CustomShape.pde +++ /dev/null @@ -1,91 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// A rectangular box -class CustomShape { - - // We need to keep track of a Body and a width and height - Body body; - - // Constructor - CustomShape(float x, float y) { - // Add the box to the box2d world - makeBody(new Vec2(x, y)); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - // Is the particle ready for deletion? - boolean done() { - // Let's find the screen position of the particle - Vec2 pos = box2d.getBodyPixelCoord(body); - // Is it off the bottom of the screen? - if (pos.y > height) { - killBody(); - return true; - } - return false; - } - - // Drawing the box - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - - Fixture f = body.getFixtureList(); - PolygonShape ps = (PolygonShape) f.getShape(); - - - rectMode(CENTER); - pushMatrix(); - translate(pos.x, pos.y); - rotate(-a); - fill(127); - stroke(0); - strokeWeight(2); - beginShape(); - //println(vertices.length); - // For every vertex, convert to pixel vector - for (int i = 0; i < ps.getVertexCount(); i++) { - Vec2 v = box2d.vectorWorldToPixels(ps.getVertex(i)); - vertex(v.x, v.y); - } - endShape(CLOSE); - popMatrix(); - } - - // This function adds the rectangle to the box2d world - void makeBody(Vec2 center) { - - Vec2[] vertices = new Vec2[4]; - vertices[0] = box2d.vectorPixelsToWorld(new Vec2(-15, 25)); - vertices[1] = box2d.vectorPixelsToWorld(new Vec2(15, 0)); - vertices[2] = box2d.vectorPixelsToWorld(new Vec2(20, -15)); - vertices[3] = box2d.vectorPixelsToWorld(new Vec2(-10, -10)); - - // Define a polygon (this is what we use for a rectangle) - PolygonShape ps = new PolygonShape(); - ps.set(vertices, vertices.length); - - // Define the body and make it from the shape - BodyDef bd = new BodyDef(); - bd.type = BodyType.DYNAMIC; - bd.position.set(box2d.coordPixelsToWorld(center)); - body = box2d.createBody(bd); - - body.createFixture(ps, 1.0); - - - // Give it some initial random velocity - body.setLinearVelocity(new Vec2(random(-5, 5), random(2, 5))); - body.setAngularVelocity(random(-5, 5)); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_4_Polygons/_5_4_Polygons.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_4_Polygons/_5_4_Polygons.pde deleted file mode 100644 index c3dc6d811..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_4_Polygons/_5_4_Polygons.pde +++ /dev/null @@ -1,74 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Basic example of falling rectangles - -import pbox2d.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; - -// A reference to our box2d world -PBox2D box2d; - -// A list we'll use to track fixed objects -ArrayList boundaries; -// A list for all of our rectangles -ArrayList polygons; - -void setup() { - size(800,200); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - // We are setting a custom gravity - box2d.setGravity(0, -20); - - // Create ArrayLists - polygons = new ArrayList(); - boundaries = new ArrayList(); - - // Add a bunch of fixed boundaries - boundaries.add(new Boundary(width/4,height-5,width/2-50,10,0)); - boundaries.add(new Boundary(3*width/4,height-50,width/2-50,10,0)); - boundaries.add(new Boundary(width-5,height/2,10,height,0)); - boundaries.add(new Boundary(5,height/2,10,height,0)); -} - -void draw() { - background(255); - - // We must always step through time! - box2d.step(); - - // Display all the boundaries - for (Boundary wall: boundaries) { - wall.display(); - } - - // Display all the people - for (CustomShape cs: polygons) { - cs.display(); - } - - // people that leave the screen, we delete them - // (note they have to be deleted from both the box2d world and our list - for (int i = polygons.size()-1; i >= 0; i--) { - CustomShape cs = polygons.get(i); - if (cs.done()) { - polygons.remove(i); - } - } -} - -void mousePressed() { - CustomShape cs = new CustomShape(mouseX,mouseY); - polygons.add(cs); -} - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_5_MultiShapes/Boundary.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_5_MultiShapes/Boundary.pde deleted file mode 100644 index ea4eebb75..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_5_MultiShapes/Boundary.pde +++ /dev/null @@ -1,62 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A fixed boundary class (now incorporates angle) - -class Boundary { - - // A boundary is a simple rectangle with x,y,width,and height - float x; - float y; - float w; - float h; - // But we also have to make a body for box2d to know about it - Body b; - - Boundary(float x_,float y_, float w_, float h_, float a) { - x = x_; - y = y_; - w = w_; - h = h_; - - // Define the polygon - PolygonShape sd = new PolygonShape(); - // Figure out the box2d coordinates - float box2dW = box2d.scalarPixelsToWorld(w/2); - float box2dH = box2d.scalarPixelsToWorld(h/2); - // We're just a box - sd.setAsBox(box2dW, box2dH); - - - // Create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.STATIC; - bd.angle = a; - bd.position.set(box2d.coordPixelsToWorld(x,y)); - b = box2d.createBody(bd); - - // Attached the shape to the body using a Fixture - b.createFixture(sd,1); - } - - // Draw the boundary, if it were at an angle we'd have to do something fancier - void display() { - fill(0); - stroke(0); - strokeWeight(1); - rectMode(CENTER); - - float a = b.getAngle(); - - pushMatrix(); - translate(x,y); - rotate(-a); - rect(0,0,w,h); - popMatrix(); - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_5_MultiShapes/Lollipop.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_5_MultiShapes/Lollipop.pde deleted file mode 100644 index 7d07373b5..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_5_MultiShapes/Lollipop.pde +++ /dev/null @@ -1,89 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// A rectangular box -class Lollipop { - - // We need to keep track of a Body and a width and height - Body body; - float w; - float h; - float r; - - // Constructor - Lollipop(float x, float y) { - w = 8; - h = 24; - r = 8; - // Add the box to the box2d world - makeBody(new Vec2(x, y)); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - // Is the particle ready for deletion? - boolean done() { - // Let's find the screen position of the particle - Vec2 pos = box2d.getBodyPixelCoord(body); - // Is it off the bottom of the screen? - if (pos.y > height+w*h) { - killBody(); - return true; - } - return false; - } - - // Drawing the lollipop - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - - rectMode(CENTER); - pushMatrix(); - translate(pos.x, pos.y); - rotate(-a); - fill(127); - stroke(0); - strokeWeight(2); - - rect(0,0,w,h); - ellipse(0, -h/2, r*2, r*2); - popMatrix(); - } - - // This function adds the rectangle to the box2d world - void makeBody(Vec2 center) { - - // Define the body and make it from the shape - BodyDef bd = new BodyDef(); - bd.type = BodyType.DYNAMIC; - bd.position.set(box2d.coordPixelsToWorld(center)); - body = box2d.createBody(bd); - - CircleShape circle = new CircleShape(); - circle.m_radius = box2d.scalarPixelsToWorld(r); - Vec2 offset = new Vec2(0,-h/2); - offset = box2d.vectorPixelsToWorld(offset); - circle.m_p.set(offset.x,offset.y); - - PolygonShape ps = new PolygonShape(); - float box2dW = box2d.scalarPixelsToWorld(w/2); - float box2dH = box2d.scalarPixelsToWorld(h/2); - ps.setAsBox(box2dW, box2dH); - - body.createFixture(ps,1.0); - body.createFixture(circle, 1.0); - - // Give it some initial random velocity - body.setLinearVelocity(new Vec2(random(-5, 5), random(2, 5))); - body.setAngularVelocity(random(-5, 5)); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_5_MultiShapes/_5_5_MultiShapes.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_5_MultiShapes/_5_5_MultiShapes.pde deleted file mode 100644 index 4ebfedfd7..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_5_MultiShapes/_5_5_MultiShapes.pde +++ /dev/null @@ -1,74 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Basic example of falling rectangles - -import pbox2d.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; - -// A reference to our box2d world -PBox2D box2d; - -// A list we'll use to track fixed objects -ArrayList boundaries; -// A list for all of our rectangles -ArrayList pops; - -void setup() { - size(800,200); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this,20); - box2d.createWorld(); - // We are setting a custom gravity - box2d.setGravity(0, -20); - - // Create ArrayLists - pops = new ArrayList(); - boundaries = new ArrayList(); - - // Add a bunch of fixed boundaries - boundaries.add(new Boundary(width/4,height-5,width/2-50,10,0)); - boundaries.add(new Boundary(3*width/4,height-50,width/2-50,10,0)); - boundaries.add(new Boundary(width-5,height/2,10,height,0)); - boundaries.add(new Boundary(5,height/2,10,height,0)); -} - -void draw() { - background(255); - - // We must always step through time! - if (mousePressed) box2d.step(); - - // Display all the boundaries - for (Boundary wall: boundaries) { - wall.display(); - } - - // Display all the people - for (Lollipop p: pops) { - p.display(); - } - - // people that leave the screen, we delete them - // (note they have to be deleted from both the box2d world and our list - for (int i = pops.size()-1; i >= 0; i--) { - Lollipop p = pops.get(i); - if (p.done()) { - pops.remove(i); - } - } -} - -void mousePressed() { - Lollipop p = new Lollipop(mouseX,mouseY); - pops.add(p); -} - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_6_DistanceJoint/Boundary.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_6_DistanceJoint/Boundary.pde deleted file mode 100644 index 7b5012517..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_6_DistanceJoint/Boundary.pde +++ /dev/null @@ -1,54 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A fixed boundary class - -class Boundary { - - // A boundary is a simple rectangle with x,y,width,and height - float x; - float y; - float w; - float h; - - // But we also have to make a body for box2d to know about it - Body b; - - Boundary(float x_,float y_, float w_, float h_) { - x = x_; - y = y_; - w = w_; - h = h_; - - // Define the polygon - PolygonShape sd = new PolygonShape(); - // Figure out the box2d coordinates - float box2dW = box2d.scalarPixelsToWorld(w/2); - float box2dH = box2d.scalarPixelsToWorld(h/2); - // We're just a box - sd.setAsBox(box2dW, box2dH); - - - // Create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.STATIC; - bd.position.set(box2d.coordPixelsToWorld(x,y)); - b = box2d.createBody(bd); - - // Attached the shape to the body using a Fixture - b.createFixture(sd,1); - } - - // Draw the boundary, if it were at an angle we'd have to do something fancier - void display() { - fill(0); - stroke(0); - rectMode(CENTER); - rect(x,y,w,h); - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_6_DistanceJoint/Pair.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_6_DistanceJoint/Pair.pde deleted file mode 100644 index d250ad1ed..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_6_DistanceJoint/Pair.pde +++ /dev/null @@ -1,48 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Series of Particles connected with distance joints - -class Pair { - - Particle p1; - Particle p2; - - float len; - // Chain constructor - Pair(float x, float y) { - len = 32; - - p1 = new Particle(x,y); - p2 = new Particle(x+random(-1,1),y+random(-1,1)); - - DistanceJointDef djd = new DistanceJointDef(); - // Connection between previous particle and this one - djd.bodyA = p1.body; - djd.bodyB = p2.body; - // Equilibrium length - djd.length = box2d.scalarPixelsToWorld(len); - - // These properties affect how springy the joint is - djd.frequencyHz = 3; // Try a value less than 5 (0 for no elasticity) - djd.dampingRatio = 0.1; // Ranges between 0 and 1 (1 for no springiness) - - // Make the joint. Note we aren't storing a reference to the joint ourselves anywhere! - // We might need to someday, but for now it's ok - DistanceJoint dj = (DistanceJoint) box2d.world.createJoint(djd); - } - - void display() { - Vec2 pos1 = box2d.getBodyPixelCoord(p1.body); - Vec2 pos2 = box2d.getBodyPixelCoord(p2.body); - stroke(0); - strokeWeight(2); - line(pos1.x,pos1.y,pos2.x,pos2.y); - - p1.display(); - p2.display(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_6_DistanceJoint/Particle.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_6_DistanceJoint/Particle.pde deleted file mode 100644 index c66da98cd..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_6_DistanceJoint/Particle.pde +++ /dev/null @@ -1,77 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// A circular particle - -class Particle { - - // We need to keep track of a Body and a radius - Body body; - float r; - - Particle(float x, float y) { - r = 8; - - // Define a body - BodyDef bd = new BodyDef(); - // Set its position - bd.position = box2d.coordPixelsToWorld(x,y); - bd.type = BodyType.DYNAMIC; - body = box2d.world.createBody(bd); - - // Make the body's shape a circle - CircleShape cs = new CircleShape(); - cs.m_radius = box2d.scalarPixelsToWorld(r); - - FixtureDef fd = new FixtureDef(); - fd.shape = cs; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.01; - fd.restitution = 0.3; - - // Attach fixture to body - body.createFixture(fd); - body.setLinearVelocity(new Vec2(random(-5, 5), random(2, 5))); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - // Is the particle ready for deletion? - boolean done() { - // Let's find the screen position of the particle - Vec2 pos = box2d.getBodyPixelCoord(body); - // Is it off the bottom of the screen? - if (pos.y > height+r*2) { - killBody(); - return true; - } - return false; - } - - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - pushMatrix(); - translate(pos.x,pos.y); - rotate(a); - fill(127); - stroke(0); - strokeWeight(2); - ellipse(0,0,r*2,r*2); - // Let's add a line so we can see the rotation - line(0,0,r,0); - popMatrix(); - } - - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_6_DistanceJoint/_5_6_DistanceJoint.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_6_DistanceJoint/_5_6_DistanceJoint.pde deleted file mode 100644 index c68edd589..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_6_DistanceJoint/_5_6_DistanceJoint.pde +++ /dev/null @@ -1,81 +0,0 @@ -// The Nature of Code -// -// Spring 201 -// PBox2D example - -// Example demonstrating distance joints -// A bridge is formed by connected a series of particles with joints - -import pbox2d.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.joints.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.collision.shapes.Shape; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; -import org.jbox2d.dynamics.contacts.*; - -// A reference to our box2d world -PBox2D box2d; - -// A list we'll use to track fixed objects -ArrayList boundaries; - - -// A list for all of our rectangles -ArrayList pairs; - -void setup() { - size(800,200); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - - // Create ArrayLists - pairs = new ArrayList(); - - boundaries = new ArrayList(); - - // Add a bunch of fixed boundaries - boundaries.add(new Boundary(width/4,height-5,width/2-50,10)); - boundaries.add(new Boundary(3*width/4,height-50,width/2-50,10)); - -} - -void draw() { - background(255); - - // We must always step through time! - box2d.step(); - - // When the mouse is clicked, add a new Box object - - // Display all the boxes - for (Pair p: pairs) { - p.display(); - } - - // Display all the boundaries - for (Boundary wall: boundaries) { - wall.display(); - } - - fill(0); - text("Click mouse to add connected particles.",10,20); -} - -void mousePressed() { - Pair p = new Pair(mouseX,mouseY); - pairs.add(p); -} - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_7_RevoluteJoint/Box.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_7_RevoluteJoint/Box.pde deleted file mode 100644 index 06410e87a..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_7_RevoluteJoint/Box.pde +++ /dev/null @@ -1,73 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// A rectangular box - -class Box { - - // We need to keep track of a Body and a width and height - Body body; - float w; - float h; - - // Constructor - Box(float x, float y, float w_, float h_, boolean lock) { - w = w_; - h = h_; - - // Define and create the body - BodyDef bd = new BodyDef(); - bd.position.set(box2d.coordPixelsToWorld(new Vec2(x,y))); - if (lock) bd.type = BodyType.STATIC; - else bd.type = BodyType.DYNAMIC; - - body = box2d.createBody(bd); - - // Define the shape -- a (this is what we use for a rectangle) - PolygonShape sd = new PolygonShape(); - float box2dW = box2d.scalarPixelsToWorld(w/2); - float box2dH = box2d.scalarPixelsToWorld(h/2); - sd.setAsBox(box2dW, box2dH); - - // Define a fixture - FixtureDef fd = new FixtureDef(); - fd.shape = sd; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.3; - fd.restitution = 0.5; - - body.createFixture(fd); - - // Give it some initial random velocity - body.setLinearVelocity(new Vec2(random(-5,5),random(2,5))); - body.setAngularVelocity(random(-5,5)); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - // Drawing the box - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - - rectMode(PConstants.CENTER); - pushMatrix(); - translate(pos.x,pos.y); - rotate(-a); - fill(127); - stroke(0); - strokeWeight(2); - rect(0,0,w,h); - popMatrix(); - } -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_7_RevoluteJoint/Particle.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_7_RevoluteJoint/Particle.pde deleted file mode 100644 index 0f64a5204..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_7_RevoluteJoint/Particle.pde +++ /dev/null @@ -1,85 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// A circular particle - -class Particle { - - // We need to keep track of a Body and a radius - Body body; - float r; - - Particle(float x, float y, float r_) { - r = r_; - // This function puts the particle in the Box2d world - makeBody(x, y, r); - body.setUserData(this); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - // Is the particle ready for deletion? - boolean done() { - // Let's find the screen position of the particle - Vec2 pos = box2d.getBodyPixelCoord(body); - // Is it off the bottom of the screen? - if (pos.y > height+r*2) { - killBody(); - return true; - } - return false; - } - - // - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - pushMatrix(); - translate(pos.x, pos.y); - - rotate(-a); - fill(127); - stroke(0); - strokeWeight(2); - ellipse(0, 0, r*2, r*2); - // Let's add a line so we can see the rotation - line(0, 0, r, 0); - popMatrix(); - } - - // Here's our function that adds the particle to the Box2D world - void makeBody(float x, float y, float r) { - // Define a body - BodyDef bd = new BodyDef(); - // Set its position - bd.position = box2d.coordPixelsToWorld(x, y); - bd.type = BodyType.DYNAMIC; - - body = box2d.world.createBody(bd); - - // Make the body's shape a circle - CircleShape cs = new CircleShape(); - cs.m_radius = box2d.scalarPixelsToWorld(r); - - FixtureDef fd = new FixtureDef(); - fd.shape = cs; - - fd.density = 2.0; - fd.friction = 0.01; - fd.restitution = 0.3; // Restitution is bounciness - - body.createFixture(fd); - - // Give it a random initial velocity (and angular velocity) - //body.setLinearVelocity(new Vec2(random(-10f,10f),random(5f,10f))); - body.setAngularVelocity(random(-10, 10)); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_7_RevoluteJoint/Windmill.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_7_RevoluteJoint/Windmill.pde deleted file mode 100644 index a25423e9b..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_7_RevoluteJoint/Windmill.pde +++ /dev/null @@ -1,62 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// Class to describe a fixed spinning object - -class Windmill { - - // Our object is two boxes and one joint - // Consider making the fixed box much smaller and not drawing it - RevoluteJoint joint; - Box box1; - Box box2; - - Windmill(float x, float y) { - - // Initialize locations of two boxes - box1 = new Box(x, y-20, 120, 10, false); - box2 = new Box(x, y, 10, 40, true); - - // Define joint as between two bodies - RevoluteJointDef rjd = new RevoluteJointDef(); - - rjd.initialize(box1.body, box2.body, box1.body.getWorldCenter()); - - // Turning on a motor (optional) - rjd.motorSpeed = PI*2; // how fast? - rjd.maxMotorTorque = 1000.0; // how powerful? - rjd.enableMotor = false; // is it on? - - // There are many other properties you can set for a Revolute joint - // For example, you can limit its angle between a minimum and a maximum - // See box2d manual for more - - - // Create the joint - joint = (RevoluteJoint) box2d.world.createJoint(rjd); - } - - // Turn the motor on or off - void toggleMotor() { - joint.enableMotor(!joint.isMotorEnabled()); - } - - boolean motorOn() { - return joint.isMotorEnabled(); - } - - - void display() { - box2.display(); - box1.display(); - - // Draw anchor just for debug - Vec2 anchor = box2d.coordWorldToPixels(box1.body.getWorldCenter()); - fill(0); - noStroke(); - ellipse(anchor.x, anchor.y, 8, 8); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_7_RevoluteJoint/_5_7_RevoluteJoint.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_7_RevoluteJoint/_5_7_RevoluteJoint.pde deleted file mode 100644 index be3681432..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_7_RevoluteJoint/_5_7_RevoluteJoint.pde +++ /dev/null @@ -1,90 +0,0 @@ -// The Nature of Code -// -// Spring 201 -// PBox2D example - -// Example demonstrating revolute joint - -import pbox2d.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.joints.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.collision.shapes.Shape; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; -import org.jbox2d.dynamics.contacts.*; - -// A reference to our box2d world -PBox2D box2d; - -// An object to describe a Windmill (two bodies and one joint) -Windmill windmill; - -// An ArrayList of particles that will fall on the surface -ArrayList particles; - -void setup() { - size(800,200); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - - // Make the windmill at an x,y location - windmill = new Windmill(width/2,175); - - // Create the empty list - particles = new ArrayList(); - -} - -// Click the mouse to turn on or off the motor -void mousePressed() { - windmill.toggleMotor(); -} - -void draw() { - background(255); - - if (random(1) < 0.1) { - float sz = random(4,8); - particles.add(new Particle(random(width/2-100,width/2+100),-20,sz)); - } - - - // We must always step through time! - box2d.step(); - - // Look at all particles - for (int i = particles.size()-1; i >= 0; i--) { - Particle p = particles.get(i); - p.display(); - // Particles that leave the screen, we delete them - // (note they have to be deleted from both the box2d world and our list - if (p.done()) { - particles.remove(i); - } - } - - // Draw the windmill - windmill.display(); - - String status = "OFF"; - if (windmill.motorOn()) status = "ON"; - - fill(0); - text("Click mouse to toggle motor.\nMotor: " + status,10,height-30); - - -} - - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_8_MouseJoint/Boundary.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_8_MouseJoint/Boundary.pde deleted file mode 100644 index a05edbf8b..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_8_MouseJoint/Boundary.pde +++ /dev/null @@ -1,63 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// A fixed boundary class (now incorporates angle) - -class Boundary { - - // A boundary is a simple rectangle with x,y,width,and height - float x; - float y; - float w; - float h; - // But we also have to make a body for box2d to know about it - Body b; - - Boundary(float x_,float y_, float w_, float h_, float a) { - x = x_; - y = y_; - w = w_; - h = h_; - - // Define the polygon - PolygonShape sd = new PolygonShape(); - // Figure out the box2d coordinates - float box2dW = box2d.scalarPixelsToWorld(w/2); - float box2dH = box2d.scalarPixelsToWorld(h/2); - // We're just a box - sd.setAsBox(box2dW, box2dH); - - - // Create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.STATIC; - bd.angle = a; - bd.position.set(box2d.coordPixelsToWorld(x,y)); - b = box2d.createBody(bd); - - // Attached the shape to the body using a Fixture - b.createFixture(sd,1); - } - - // Draw the boundary, if it were at an angle we'd have to do something fancier - void display() { - noFill(); - stroke(127); - fill(127); - strokeWeight(1); - rectMode(CENTER); - - float a = b.getAngle(); - - pushMatrix(); - translate(x,y); - rotate(-a); - rect(0,0,w,h); - popMatrix(); - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_8_MouseJoint/Box.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_8_MouseJoint/Box.pde deleted file mode 100644 index f3a872879..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_8_MouseJoint/Box.pde +++ /dev/null @@ -1,89 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// A rectangular box - -class Box { - - // We need to keep track of a Body and a width and height - Body body; - float w; - float h; - - // Constructor - Box(float x_, float y_) { - float x = x_; - float y = y_; - w = 24; - h = 24; - // Add the box to the box2d world - makeBody(new Vec2(x,y),w,h); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - boolean contains(float x, float y) { - Vec2 worldPoint = box2d.coordPixelsToWorld(x, y); - Fixture f = body.getFixtureList(); - boolean inside = f.testPoint(worldPoint); - return inside; - } - - // Drawing the box - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - - rectMode(PConstants.CENTER); - pushMatrix(); - translate(pos.x,pos.y); - rotate(a); - fill(127); - stroke(0); - strokeWeight(2); - rect(0,0,w,h); - popMatrix(); - } - - - // This function adds the rectangle to the box2d world - void makeBody(Vec2 center, float w_, float h_) { - // Define and create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.DYNAMIC; - bd.position.set(box2d.coordPixelsToWorld(center)); - body = box2d.createBody(bd); - - // Define a polygon (this is what we use for a rectangle) - PolygonShape sd = new PolygonShape(); - float box2dW = box2d.scalarPixelsToWorld(w_/2); - float box2dH = box2d.scalarPixelsToWorld(h_/2); - sd.setAsBox(box2dW, box2dH); - - // Define a fixture - FixtureDef fd = new FixtureDef(); - fd.shape = sd; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.3; - fd.restitution = 0.5; - - body.createFixture(fd); - //body.setMassFromShapes(); - - // Give it some initial random velocity - body.setLinearVelocity(new Vec2(random(-5, 5), random(2, 5))); - body.setAngularVelocity(random(-5, 5)); - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_8_MouseJoint/Spring.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_8_MouseJoint/Spring.pde deleted file mode 100644 index 76c445d50..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_8_MouseJoint/Spring.pde +++ /dev/null @@ -1,78 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// Class to describe the spring joint (displayed as a line) - -class Spring { - - // This is the box2d object we need to create - MouseJoint mouseJoint; - - Spring() { - // At first it doesn't exist - mouseJoint = null; - } - - // If it exists we set its target to the mouse location - void update(float x, float y) { - if (mouseJoint != null) { - // Always convert to world coordinates! - Vec2 mouseWorld = box2d.coordPixelsToWorld(x,y); - mouseJoint.setTarget(mouseWorld); - } - } - - void display() { - if (mouseJoint != null) { - // We can get the two anchor points - Vec2 v1 = new Vec2(0,0); - mouseJoint.getAnchorA(v1); - Vec2 v2 = new Vec2(0,0); - mouseJoint.getAnchorB(v2); - // Convert them to screen coordinates - v1 = box2d.coordWorldToPixels(v1); - v2 = box2d.coordWorldToPixels(v2); - // And just draw a line - stroke(0); - strokeWeight(1); - line(v1.x,v1.y,v2.x,v2.y); - } - } - - - // This is the key function where - // we attach the spring to an x,y location - // and the Box object's location - void bind(float x, float y, Box box) { - // Define the joint - MouseJointDef md = new MouseJointDef(); - // Body A is just a fake ground body for simplicity (there isn't anything at the mouse) - md.bodyA = box2d.getGroundBody(); - // Body 2 is the box's boxy - md.bodyB = box.body; - // Get the mouse location in world coordinates - Vec2 mp = box2d.coordPixelsToWorld(x,y); - // And that's the target - md.target.set(mp); - // Some stuff about how strong and bouncy the spring should be - md.maxForce = 1000.0 * box.body.m_mass; - md.frequencyHz = 5.0; - md.dampingRatio = 0.9; - - // Make the joint! - mouseJoint = (MouseJoint) box2d.world.createJoint(md); - } - - void destroy() { - // We can get rid of the joint when the mouse is released - if (mouseJoint != null) { - box2d.world.destroyJoint(mouseJoint); - mouseJoint = null; - } - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_8_MouseJoint/_5_8_MouseJoint.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_8_MouseJoint/_5_8_MouseJoint.pde deleted file mode 100644 index 564f716cd..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_8_MouseJoint/_5_8_MouseJoint.pde +++ /dev/null @@ -1,86 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Basic example of controlling an object with the mouse (by attaching a spring) - -import pbox2d.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.joints.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.collision.shapes.Shape; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; - -// A reference to our box2d world -PBox2D box2d; - -// A list we'll use to track fixed objects -ArrayList boundaries; - -// Just a single box this time -Box box; - -// The Spring that will attach to the box from the mouse -Spring spring; - -void setup() { - size(800,200); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - - // Make the box - box = new Box(width/2,height/2); - - // Make the spring (it doesn't really get initialized until the mouse is clicked) - spring = new Spring(); - - // Add a bunch of fixed boundaries - boundaries = new ArrayList(); - boundaries.add(new Boundary(width/2,height-5,width,10,0)); - boundaries.add(new Boundary(width/2,5,width,10,0)); - boundaries.add(new Boundary(width-5,height/2,10,height,0)); - boundaries.add(new Boundary(5,height/2,10,height,0)); -} - -// When the mouse is released we're done with the spring -void mouseReleased() { - spring.destroy(); -} - -// When the mouse is pressed we. . . -void mousePressed() { - // Check to see if the mouse was clicked on the box - if (box.contains(mouseX, mouseY)) { - // And if so, bind the mouse location to the box with a spring - spring.bind(mouseX,mouseY,box); - } -} - -void draw() { - background(255); - - // We must always step through time! - box2d.step(); - - // Always alert the spring to the new mouse location - spring.update(mouseX,mouseY); - - // Draw the boundaries - for (int i = 0; i < boundaries.size(); i++) { - Boundary wall = (Boundary) boundaries.get(i); - wall.display(); - } - - // Draw the box - box.display(); - // Draw the spring (it only appears when active) - spring.display(); -} - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_9_CollisionListening/Boundary.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_9_CollisionListening/Boundary.pde deleted file mode 100644 index 06c5bf80d..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_9_CollisionListening/Boundary.pde +++ /dev/null @@ -1,56 +0,0 @@ -// The Nature of Code -// -// Spring 2012 -// PBox2D example - -// A fixed boundary class - -class Boundary { - - // A boundary is a simple rectangle with x,y,width,and height - float x; - float y; - float w; - float h; - - // But we also have to make a body for box2d to know about it - Body b; - - Boundary(float x_,float y_, float w_, float h_) { - x = x_; - y = y_; - w = w_; - h = h_; - - // Define the polygon - PolygonShape sd = new PolygonShape(); - // Figure out the box2d coordinates - float box2dW = box2d.scalarPixelsToWorld(w/2); - float box2dH = box2d.scalarPixelsToWorld(h/2); - // We're just a box - sd.setAsBox(box2dW, box2dH); - - - // Create the body - BodyDef bd = new BodyDef(); - bd.type = BodyType.STATIC; - bd.position.set(box2d.coordPixelsToWorld(x,y)); - b = box2d.createBody(bd); - - // Attached the shape to the body using a Fixture - b.createFixture(sd,1); - - b.setUserData(this); - } - - // Draw the boundary, if it were at an angle we'd have to do something fancier - void display() { - fill(0); - stroke(0); - rectMode(CENTER); - rect(x,y,w,h); - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_9_CollisionListening/Particle.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_9_CollisionListening/Particle.pde deleted file mode 100644 index 7d92ef9f6..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_9_CollisionListening/Particle.pde +++ /dev/null @@ -1,91 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// PBox2D example - -// A circular particle - -class Particle { - - // We need to keep track of a Body and a radius - Body body; - float r; - - color col; - - Particle(float x, float y, float r_) { - r = r_; - // This function puts the particle in the Box2d world - makeBody(x, y, r); - body.setUserData(this); - col = color(127); - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - // Change color when hit - void change() { - col = color(255, 0, 0); - } - - // Is the particle ready for deletion? - boolean done() { - // Let's find the screen position of the particle - Vec2 pos = box2d.getBodyPixelCoord(body); - // Is it off the bottom of the screen? - if (pos.y > height+r*2) { - killBody(); - return true; - } - return false; - } - - - // - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - // Get its angle of rotation - float a = body.getAngle(); - pushMatrix(); - translate(pos.x, pos.y); - rotate(a); - fill(col); - stroke(0); - strokeWeight(2); - ellipse(0, 0, r*2, r*2); - // Let's add a line so we can see the rotation - line(0, 0, r, 0); - popMatrix(); - } - - // Here's our function that adds the particle to the Box2D world - void makeBody(float x, float y, float r) { - // Define a body - BodyDef bd = new BodyDef(); - // Set its position - bd.position = box2d.coordPixelsToWorld(x, y); - bd.type = BodyType.DYNAMIC; - body = box2d.createBody(bd); - - // Make the body's shape a circle - CircleShape cs = new CircleShape(); - cs.m_radius = box2d.scalarPixelsToWorld(r); - - FixtureDef fd = new FixtureDef(); - fd.shape = cs; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.01; - fd.restitution = 0.3; - - // Attach fixture to body - body.createFixture(fd); - - body.setAngularVelocity(random(-10, 10)); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_9_CollisionListening/_5_9_CollisionListening.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_9_CollisionListening/_5_9_CollisionListening.pde deleted file mode 100644 index 2d5f843e3..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/NOC_5_9_CollisionListening/_5_9_CollisionListening.pde +++ /dev/null @@ -1,111 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Basic example of controlling an object with our own motion (by attaching a MouseJoint) -// Also demonstrates how to know which object was hit - -import pbox2d.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.joints.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.collision.shapes.Shape; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; -import org.jbox2d.dynamics.contacts.*; - -// A reference to our box2d world -PBox2D box2d; - -// An ArrayList of particles that will fall on the surface -ArrayList particles; - -Boundary wall; - -void setup() { - size(800, 200); - smooth(); - - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - - // Turn on collision listening! - box2d.listenForCollisions(); - - // Create the empty list - particles = new ArrayList(); - - wall = new Boundary(width/2, height-5, width, 10); -} - -void draw() { - background(255); - - if (random(1) < 0.1) { - float sz = random(4, 8); - particles.add(new Particle(random(width), 20, sz)); - } - - - // We must always step through time! - box2d.step(); - - // Look at all particles - for (int i = particles.size()-1; i >= 0; i--) { - Particle p = particles.get(i); - p.display(); - // Particles that leave the screen, we delete them - // (note they have to be deleted from both the box2d world and our list - if (p.done()) { - particles.remove(i); - } - } - - wall.display(); -} - - -// Collision event functions! -void beginContact(Contact cp) { - // Get both fixtures - Fixture f1 = cp.getFixtureA(); - Fixture f2 = cp.getFixtureB(); - // Get both bodies - Body b1 = f1.getBody(); - Body b2 = f2.getBody(); - - // Get our objects that reference these bodies - Object o1 = b1.getUserData(); - Object o2 = b2.getUserData(); - - if (o1.getClass() == Particle.class && o2.getClass() == Particle.class) { - Particle p1 = (Particle) o1; - p1.change(); - Particle p2 = (Particle) o2; - p2.change(); - } - -} - -// Objects stop touching each other -void endContact(Contact cp) { -} - - - - - - - - - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/VectorStuff/VectorStuff.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/VectorStuff/VectorStuff.pde deleted file mode 100644 index a89fd6eb5..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/box2d/VectorStuff/VectorStuff.pde +++ /dev/null @@ -1,57 +0,0 @@ -// The Nature of Code -// -// Spring 2011 -// PBox2D example - -// Just demo-ing the basics of Vec2 vs. PVector - -import org.jbox2d.common.*; - -void setup() { - size(400,300); -// PVector a = new PVector(1,-1); -// PVector b = new PVector(3,4); -// a.add(b); -// -// PVector a = new PVector(1,-1); -// PVector b = new PVector(3,4); -// PVector c = PVector.add(a,b); -// -// Vec2 a = new Vec2(1,-1); -// Vec2 b = new Vec2(3,4); -// a.addLocal(b); -// -// Vec2 a = new Vec2(1,-1); -// Vec2 b = new Vec2(3,4); -// Vec2 c = a.add(b); -// -// PVector a = new PVector(1,-1); -// float n = 5; -// a.mult(n); -// -// PVector a = new PVector(1,-1); -// float n = 5; -// PVector c = PVector.mult(a,n); -// -// Vec2 a = new Vec2(1,-1); -// float n = 5; -// a.mulLocal(n); -// -// Vec2 a = new Vec2(1,-1); -// float n = 5; -// Vec2 c = a.mul(n); -// -// PVector a = new PVector(1,-1); -// float m = a.mag(); -// a.normalize(); - - Vec2 a = new Vec2(1,-1); - float m = a.length(); - a.normalize(); - println(a.x + "," + a.y); -} - -void draw() { - noLoop(); -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/readme.txt b/java/examples/Books/Nature of Code/chp5_physicslibraries/readme.txt deleted file mode 100644 index 99d3a27ad..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/readme.txt +++ /dev/null @@ -1,3 +0,0 @@ -For the box2d examples you will need PBox2D! - -https://github.com/shiffman/PBox2D \ No newline at end of file diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_13_SoftBodySquareAdapted/Blanket.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_13_SoftBodySquareAdapted/Blanket.pde deleted file mode 100644 index 70a45340b..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_13_SoftBodySquareAdapted/Blanket.pde +++ /dev/null @@ -1,51 +0,0 @@ -class Blanket { - ArrayList particles; - ArrayList springs; - - Blanket() { - particles = new ArrayList(); - springs = new ArrayList(); - - int w = 20; - int h = 20; - - float len = 10; - float strength = 0.125; - - for(int y=0; y< h; y++) { - for(int x=0; x < w; x++) { - - Particle p = new Particle(new Vec2D(width/2+x*len-w*len/2,y*len)); - physics.addParticle(p); - particles.add(p); - - if (x > 0) { - Particle previous = particles.get(particles.size()-2); - Connection c = new Connection(p,previous,len,strength); - physics.addSpring(c); - springs.add(c); - } - - if (y > 0) { - Particle above = particles.get(particles.size()-w-1); - Connection c=new Connection(p,above,len,strength); - physics.addSpring(c); - springs.add(c); - } - } - } - - Particle topleft= particles.get(0); - topleft.lock(); - - Particle topright = particles.get(w-1); - topright.lock(); - } - - void display() { - for (Connection c : springs) { - c.display(); - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_13_SoftBodySquareAdapted/Connection.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_13_SoftBodySquareAdapted/Connection.pde deleted file mode 100644 index 692d3f9ab..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_13_SoftBodySquareAdapted/Connection.pde +++ /dev/null @@ -1,11 +0,0 @@ -class Connection extends VerletSpring2D { - Connection(Particle p1, Particle p2, float len, float strength) { - super(p1,p2,len,strength); - } - - void display() { - stroke(0); - line(a.x,a.y,b.x,b.y); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_13_SoftBodySquareAdapted/Ex_5_13_SoftBodySquareAdapted.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_13_SoftBodySquareAdapted/Ex_5_13_SoftBodySquareAdapted.pde deleted file mode 100644 index 78aa8c09b..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_13_SoftBodySquareAdapted/Ex_5_13_SoftBodySquareAdapted.pde +++ /dev/null @@ -1,63 +0,0 @@ -/** - * This example is adapted from Karsten Schmidt's SoftBodySquare example - * Daniel Shiffman, 2011 - * The Nature of Code book - */ - -/*

Softbody square demo is showing how to create a 2D square mesh out of - * verlet particles and make it stable enough to avoid total structural - * deformation by including an inner skeleton.

- * - *

Usage: move mouse to drag/deform the square

- */ - -/* - * Copyright (c) 2008-2009 Karsten Schmidt - * - * This demo & library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * http://creativecommons.org/licenses/LGPL/2.1/ - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -import toxi.physics2d.behaviors.*; -import toxi.physics2d.*; - -import toxi.geom.*; -import toxi.math.*; - -VerletPhysics2D physics; - -Blanket b; - - -void setup() { - size(800,240); - smooth(); - physics=new VerletPhysics2D(); - physics.addBehavior(new GravityBehavior(new Vec2D(0,0.1))); - - b = new Blanket(); -} - -void draw() { - - background(255); - - physics.update(); - - b.display(); -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_13_SoftBodySquareAdapted/Particle.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_13_SoftBodySquareAdapted/Particle.pde deleted file mode 100644 index 41a73d4c2..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_13_SoftBodySquareAdapted/Particle.pde +++ /dev/null @@ -1,17 +0,0 @@ -// Notice how we are using inheritance here! -// We could have just stored a reference to a VerletParticle object -// inside the Particle class, but inheritance is a nice alternative - -class Particle extends VerletParticle2D { - - Particle(Vec2D loc) { - super(loc); - } - - // All we're doing really is adding a display() function to a VerletParticle - void display() { - fill(175); - stroke(0); - ellipse(x,y,16,16); - } -} diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_15_ForceDirectedGraph/Cluster.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_15_ForceDirectedGraph/Cluster.pde deleted file mode 100644 index e2629412e..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_15_ForceDirectedGraph/Cluster.pde +++ /dev/null @@ -1,99 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// Toxiclibs example: http://toxiclibs.org/ - -// Force directed graph -// Heavily based on: http://code.google.com/p/fidgen/ - -class Cluster { - - // A cluster is a grouping of nodes - ArrayList nodes; - - float diameter; - - // We initialize a Cluster with a number of nodes, a diameter, and centerpoint - Cluster(int n, float d, Vec2D center) { - - // Initialize the ArrayList - nodes = new ArrayList(); - - // Set the diameter - diameter = d; - - // Create the nodes - for (int i = 0; i < n; i++) { - // We can't put them right on top of each other - nodes.add(new Node(center.add(Vec2D.randomVector()))); - } - - // Connect all the nodes with a Spring - for (int i = 1; i < nodes.size(); i++) { - VerletParticle2D pi = (VerletParticle2D) nodes.get(i); - for (int j = 0; j < i; j++) { - VerletParticle2D pj = (VerletParticle2D) nodes.get(j); - // A Spring needs two particles, a resting length, and a strength - physics.addSpring(new VerletSpring2D(pi,pj,diameter,0.01)); - } - } - } - - void display() { - // Show all the nodes - for (int i = 0; i < nodes.size(); i++) { - Node n = (Node) nodes.get(i); - n.display(); - } - } - - // This functons connects one cluster to another - // Each point of one cluster connects to each point of the other cluster - // The connection is a "VerletMinDistanceSpring" - // A VerletMinDistanceSpring is a string which only enforces its rest length if the - // current distance is less than its rest length. This is handy if you just want to - // ensure objects are at least a certain distance from each other, but don't - // care if it's bigger than the enforced minimum. - void connect(Cluster other) { - ArrayList otherNodes = other.getNodes(); - for (int i = 0; i < nodes.size(); i++) { - VerletParticle2D pi = (VerletParticle2D) nodes.get(i); - for (int j = 0; j < otherNodes.size(); j++) { - VerletParticle2D pj = (VerletParticle2D) otherNodes.get(j); - // Create the spring - physics.addSpring(new VerletMinDistanceSpring2D(pi,pj,(diameter+other.diameter)*0.5,0.05)); - } - } - } - - - // Draw all the internal connections - void showConnections() { - stroke(0,150); - for (int i = 0; i < nodes.size(); i++) { - VerletParticle2D pi = (VerletParticle2D) nodes.get(i); - for (int j = i+1; j < nodes.size(); j++) { - VerletParticle2D pj = (VerletParticle2D) nodes.get(j); - line(pi.x,pi.y,pj.x,pj.y); - } - } - } - - // Draw all the connections between this Cluster and another Cluster - void showConnections(Cluster other) { - stroke(0,50); - strokeWeight(2); - ArrayList otherNodes = other.getNodes(); - for (int i = 0; i < nodes.size(); i++) { - VerletParticle2D pi = (VerletParticle2D) nodes.get(i); - for (int j = 0; j < otherNodes.size(); j++) { - VerletParticle2D pj = (VerletParticle2D) otherNodes.get(j); - line(pi.x,pi.y,pj.x,pj.y); - } - } - } - - ArrayList getNodes() { - return nodes; - } -} diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_15_ForceDirectedGraph/Ex_5_15_ForceDirectedGraph.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_15_ForceDirectedGraph/Ex_5_15_ForceDirectedGraph.pde deleted file mode 100644 index b6e4982d1..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_15_ForceDirectedGraph/Ex_5_15_ForceDirectedGraph.pde +++ /dev/null @@ -1,134 +0,0 @@ -/** - *

Force directed graph, - * heavily based on: fid.gen
- * The Nature of Code
- * Spring 2010

- */ - -/* - * Copyright (c) 2010 Daniel Schiffmann - * - * This demo & library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * http://creativecommons.org/licenses/LGPL/2.1/ - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -import toxi.geom.*; -import toxi.physics2d.*; -import toxi.physics2d.behaviors.*; - -// Reference to physics world -VerletPhysics2D physics; - -// A list of cluster objects -ArrayList clusters; - -// Boolean that indicates whether we draw connections or not -boolean showPhysics = true; -boolean showParticles = true; - -// Font -PFont f; - -void setup() { - size(800,300); - smooth(); - f = createFont("Georgia",12,true); - - // Initialize the physics - physics=new VerletPhysics2D(); - physics.setWorldBounds(new Rect(10,10,width-20,height-20)); - - // Spawn a new random graph - newGraph(); - -} - -// Spawn a new random graph -void newGraph() { - - // Clear physics - physics.clear(); - - // Create new ArrayList (clears old one) - clusters = new ArrayList(); - - // Create 8 random clusters - for (int i = 0; i < 8; i++) { - Vec2D center = new Vec2D(width/2,height/2); - clusters.add(new Cluster((int) random(3,8),random(20,100),center)); - } - - // All clusters connect to all clusters - for (int i = 0; i < clusters.size(); i++) { - for (int j = i+1; j < clusters.size(); j++) { - Cluster ci = (Cluster) clusters.get(i); - Cluster cj = (Cluster) clusters.get(j); - ci.connect(cj); - } - } - -} - -void draw() { - - // Update the physics world - physics.update(); - - background(255); - - // Display all points - if (showParticles) { - for (int i = 0; i < clusters.size(); i++) { - Cluster c = (Cluster) clusters.get(i); - c.display(); - } - } - - // If we want to see the physics - if (showPhysics) { - for (int i = 0; i < clusters.size(); i++) { - // Cluster internal connections - Cluster ci = (Cluster) clusters.get(i); - ci.showConnections(); - - // Cluster connections to other clusters - for (int j = i+1; j < clusters.size(); j++) { - Cluster cj = (Cluster) clusters.get(j); - ci.showConnections(cj); - } - } - } - - // Instructions - fill(0); - textFont(f); - text("'p' to display or hide particles\n'c' to display or hide connections\n'n' for new graph",10,20); -} - -// Key press commands -void keyPressed() { - if (key == 'c') { - showPhysics = !showPhysics; - if (!showPhysics) showParticles = true; - } - else if (key == 'p') { - showParticles = !showParticles; - if (!showParticles) showPhysics = true; - } - else if (key == 'n') { - newGraph(); - } -} diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_15_ForceDirectedGraph/Node.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_15_ForceDirectedGraph/Node.pde deleted file mode 100644 index 6fe3b5144..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/Exercise_5_15_ForceDirectedGraph/Node.pde +++ /dev/null @@ -1,27 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// Toxiclibs example: http://toxiclibs.org/ - -// Force directed graph -// Heavily based on: http://code.google.com/p/fidgen/ - -// Notice how we are using inheritance here! -// We could have just stored a reference to a VerletParticle object -// inside the Node class, but inheritance is a nice alternative - -class Node extends VerletParticle2D { - - Node(Vec2D pos) { - super(pos); - } - - // All we're doing really is adding a display() function to a VerletParticle - void display() { - fill(0,150); - stroke(0); - strokeWeight(2); - ellipse(x,y,16,16); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_10_SimpleSpring/Particle.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_10_SimpleSpring/Particle.pde deleted file mode 100644 index 5d15d4d44..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_10_SimpleSpring/Particle.pde +++ /dev/null @@ -1,18 +0,0 @@ -// Notice how we are using inheritance here! -// We could have just stored a reference to a VerletParticle object -// inside the Particle class, but inheritance is a nice alternative - -class Particle extends VerletParticle2D { - - Particle(Vec2D loc) { - super(loc); - } - - // All we're doing really is adding a display() function to a VerletParticle - void display() { - fill(127); - stroke(0); - strokeWeight(2); - ellipse(x,y,32,32); - } -} diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_10_SimpleSpring/_5_10_SimpleSpring.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_10_SimpleSpring/_5_10_SimpleSpring.pde deleted file mode 100644 index 95b877cf7..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_10_SimpleSpring/_5_10_SimpleSpring.pde +++ /dev/null @@ -1,70 +0,0 @@ -// The Nature of Code -// -// PBox2D example - -// Simple Toxiclibs Spring - -import toxi.physics2d.*; -import toxi.physics2d.behaviors.*; -import toxi.geom.*; - -// Reference to physics world -VerletPhysics2D physics; - -Particle p1; -Particle p2; - -void setup() { - size(800,200); - smooth(); - frameRate(30); - - // Initialize the physics - physics=new VerletPhysics2D(); - physics.addBehavior(new GravityBehavior(new Vec2D(0,0.5))); - - // Set the world's bounding box - physics.setWorldBounds(new Rect(0,0,width,height)); - - // Make two particles - p1 = new Particle(new Vec2D(width/2,20)); - p2 = new Particle(new Vec2D(width,180)); - // Lock one in place - p1.lock(); - - // Make a spring connecting both Particles - VerletSpring2D spring=new VerletSpring2D(p1,p2,80,0.01); - - // Anything we make, we have to add into the physics world - physics.addParticle(p1); - physics.addParticle(p2); - physics.addSpring(spring); -} - -void draw() { - - // Update the physics world - physics.update(); - - background(255); - - // Draw a line between the particles - stroke(0); - strokeWeight(2); - line(p1.x,p1.y,p2.x,p2.y); - - // Display the particles - p1.display(); - p2.display(); - - // Move the second one according to the mouse - if (mousePressed) { - p2.lock(); - p2.x = mouseX; - p2.y = mouseY; - p2.unlock(); - } -} - - - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_11_SoftStringPendulum/Chain.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_11_SoftStringPendulum/Chain.pde deleted file mode 100644 index e9703ed21..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_11_SoftStringPendulum/Chain.pde +++ /dev/null @@ -1,104 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// Toxiclibs example - -// A soft pendulum (series of connected springs) - -class Chain { - - // Chain properties - float totalLength; // How long - int numPoints; // How many points - float strength; // Strength of springs - float radius; // Radius of ball at tail - - // This list is redundant since we can ask for physics.particles, but in case we have many of these - // it's a convenient to keep track of our own list - ArrayList particles; - - // Let's keep an extra reference to the tail particle - // This is just the last particle in the ArrayList - Particle tail; - - // Some variables for mouse dragging - PVector offset = new PVector(); - boolean dragged = false; - - // Chain constructor - Chain(float l, int n, float r, float s) { - particles = new ArrayList(); - - totalLength = l; - numPoints = n; - radius = r; - strength = s; - - float len = totalLength / numPoints; - - // Here is the real work, go through and add particles to the chain itself - for(int i=0; i < numPoints; i++) { - // Make a new particle with an initial starting location - Particle particle=new Particle(width/2,i*len); - - // Redundancy, we put the particles both in physics and in our own ArrayList - physics.addParticle(particle); - particles.add(particle); - - // Connect the particles with a Spring (except for the head) - if (i != 0) { - Particle previous = particles.get(i-1); - VerletSpring2D spring = new VerletSpring2D(particle,previous,len,strength); - // Add the spring to the physics world - physics.addSpring(spring); - } - } - - // Keep the top fixed - Particle head=particles.get(0); - head.lock(); - - // Store reference to the tail - tail = particles.get(numPoints-1); - tail.radius = radius; - } - - // Check if a point is within the ball at the end of the chain - // If so, set dragged = true; - void contains(int x, int y) { - float d = dist(x,y,tail.x,tail.y); - if (d < radius) { - offset.x = tail.x - x; - offset.y = tail.y - y; - tail.lock(); - dragged = true; - } - } - - // Release the ball - void release() { - tail.unlock(); - dragged = false; - } - - // Update tail location if being dragged - void updateTail(int x, int y) { - if (dragged) { - tail.set(x+offset.x,y+offset.y); - } - } - - // Draw the chain - void display() { - // Draw line connecting all points - beginShape(); - stroke(0); - strokeWeight(2); - noFill(); - for (Particle p : particles) { - vertex(p.x,p.y); - } - endShape(); - tail.display(); - } -} diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_11_SoftStringPendulum/Particle.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_11_SoftStringPendulum/Particle.pde deleted file mode 100644 index da2de8b4f..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_11_SoftStringPendulum/Particle.pde +++ /dev/null @@ -1,20 +0,0 @@ -// Notice how we are using inheritance here! -// We could have just stored a reference to a VerletParticle object -// inside the Particle class, but inheritance is a nice alternative - -class Particle extends VerletParticle2D { - - float radius = 4; // Adding a radius for each particle - - Particle(float x, float y) { - super(x,y); - } - - // All we're doing really is adding a display() function to a VerletParticle - void display() { - fill(127); - stroke(0); - strokeWeight(2); - ellipse(x,y,radius*2,radius*2); - } -} diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_11_SoftStringPendulum/_5_11_SoftStringPendulum.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_11_SoftStringPendulum/_5_11_SoftStringPendulum.pde deleted file mode 100644 index c79572ca2..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_11_SoftStringPendulum/_5_11_SoftStringPendulum.pde +++ /dev/null @@ -1,70 +0,0 @@ -/** - *

A soft pendulum (series of connected springs)
- * The Nature of Code
- * Spring 2010

- */ - -/* - * Copyright (c) 2010 Daniel Shiffmann - * - * This demo & library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * http://creativecommons.org/licenses/LGPL/2.1/ - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -import toxi.physics2d.*; -import toxi.physics2d.behaviors.*; -import toxi.geom.*; - -// Reference to physics "world" (2D) -VerletPhysics2D physics; - -// Our "Chain" object -Chain chain; - -void setup() { - size(800, 200); - smooth(); - - // Initialize the physics world - physics=new VerletPhysics2D(); - physics.addBehavior(new GravityBehavior(new Vec2D(0, 0.1))); - physics.setWorldBounds(new Rect(0, 0, width, height)); - - // Initialize the chain - chain = new Chain(180, 20, 16, 0.2); -} - -void draw() { - background(255); - - // Update physics - physics.update(); - // Update chain's tail according to mouse location - chain.updateTail(mouseX, mouseY); - // Display chain - chain.display(); -} - -void mousePressed() { - // Check to see if we're grabbing the chain - chain.contains(mouseX, mouseY); -} - -void mouseReleased() { - // Release the chain - chain.release(); -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_12_SimpleCluster/Cluster.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_12_SimpleCluster/Cluster.pde deleted file mode 100644 index 241520f2b..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_12_SimpleCluster/Cluster.pde +++ /dev/null @@ -1,64 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// Toxiclibs example: http://toxiclibs.org/ - -// Force directed graph -// Heavily based on: http://code.google.com/p/fidgen/ - -class Cluster { - - // A cluster is a grouping of nodes - ArrayList nodes; - - float diameter; - - // We initialize a Cluster with a number of nodes, a diameter, and centerpoint - Cluster(int n, float d, Vec2D center) { - - // Initialize the ArrayList - nodes = new ArrayList(); - - // Set the diameter - diameter = d; - - // Create the nodes - for (int i = 0; i < n; i++) { - // We can't put them right on top of each other - nodes.add(new Node(center.add(Vec2D.randomVector()))); - } - - // Connect all the nodes with a Spring - for (int i = 0; i < nodes.size()-1; i++) { - VerletParticle2D ni = nodes.get(i); - for (int j = i+1; j < nodes.size(); j++) { - VerletParticle2D nj = nodes.get(j); - // A Spring needs two particles, a resting length, and a strength - physics.addSpring(new VerletSpring2D(ni, nj, diameter, 0.01)); - } - } - } - - void display() { - // Show all the nodes - for (Node n : nodes) { - n.display(); - } - } - - - // Draw all the internal connections - void showConnections() { - stroke(0, 150); - strokeWeight(2); - for (int i = 0; i < nodes.size()-1; i++) { - VerletParticle2D pi = (VerletParticle2D) nodes.get(i); - for (int j = i+1; j < nodes.size(); j++) { - VerletParticle2D pj = (VerletParticle2D) nodes.get(j); - - line(pi.x, pi.y, pj.x, pj.y); - } - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_12_SimpleCluster/Node.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_12_SimpleCluster/Node.pde deleted file mode 100644 index 6fe3b5144..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_12_SimpleCluster/Node.pde +++ /dev/null @@ -1,27 +0,0 @@ -// The Nature of Code -// -// Spring 2010 -// Toxiclibs example: http://toxiclibs.org/ - -// Force directed graph -// Heavily based on: http://code.google.com/p/fidgen/ - -// Notice how we are using inheritance here! -// We could have just stored a reference to a VerletParticle object -// inside the Node class, but inheritance is a nice alternative - -class Node extends VerletParticle2D { - - Node(Vec2D pos) { - super(pos); - } - - // All we're doing really is adding a display() function to a VerletParticle - void display() { - fill(0,150); - stroke(0); - strokeWeight(2); - ellipse(x,y,16,16); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_12_SimpleCluster/_5_12_SimpleCluster.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_12_SimpleCluster/_5_12_SimpleCluster.pde deleted file mode 100644 index 0191d5201..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_12_SimpleCluster/_5_12_SimpleCluster.pde +++ /dev/null @@ -1,76 +0,0 @@ -/** - *

Force directed graph, - * heavily based on: fid.gen
- * The Nature of Code
- * Spring 2010

- */ - -import toxi.geom.*; -import toxi.physics2d.*; - -// Reference to physics world -VerletPhysics2D physics; - -// A list of cluster objects -Cluster cluster; - -// Boolean that indicates whether we draw connections or not -boolean showPhysics = true; -boolean showParticles = true; - -// Font -PFont f; - -void setup() { - size(800, 200); - smooth(); - frameRate(30); - f = createFont("Georgia", 12, true); - - // Initialize the physics - physics=new VerletPhysics2D(); - physics.setWorldBounds(new Rect(10, 10, width-20, height-20)); - - // Spawn a new random graph - cluster = new Cluster(8, 100, new Vec2D(width/2, height/2)); -} - -void draw() { - - // Update the physics world - physics.update(); - - background(255); - - // Display all points - if (showParticles) { - cluster.display(); - } - - // If we want to see the physics - if (showPhysics) { - cluster.showConnections(); - } - - // Instructions - fill(0); - textFont(f); - text("'p' to display or hide particles\n'c' to display or hide connections\n'n' for new graph",10,20); -} - -// Key press commands -void keyPressed() { - if (key == 'c') { - showPhysics = !showPhysics; - if (!showPhysics) showParticles = true; - } - else if (key == 'p') { - showParticles = !showParticles; - if (!showParticles) showPhysics = true; - } - else if (key == 'n') { - physics.clear(); - cluster = new Cluster(int(random(2, 20)), random(10, width/2), new Vec2D(width/2, height/2)); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_13_AttractRepel/Attractor.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_13_AttractRepel/Attractor.pde deleted file mode 100644 index e82810ee1..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_13_AttractRepel/Attractor.pde +++ /dev/null @@ -1,17 +0,0 @@ -class Attractor extends VerletParticle2D { - - float r; - - Attractor (Vec2D loc) { - super (loc); - r = 24; - physics.addParticle(this); - physics.addBehavior(new AttractionBehavior(this, width, 0.1)); - } - - void display () { - fill(0); - ellipse (x, y, r*2, r*2); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_13_AttractRepel/Particle.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_13_AttractRepel/Particle.pde deleted file mode 100644 index a33163d71..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_13_AttractRepel/Particle.pde +++ /dev/null @@ -1,20 +0,0 @@ -// class Spore extends the class "VerletParticle2D" -class Particle extends VerletParticle2D { - - float r; - - Particle (Vec2D loc) { - super(loc); - r = 8; - physics.addParticle(this); - physics.addBehavior(new AttractionBehavior(this, r*4, -1)); - } - - void display () { - fill (127); - stroke (0); - strokeWeight(2); - ellipse (x, y, r*2, r*2); - } -} - diff --git a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_13_AttractRepel/_5_13_AttractRepel.pde b/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_13_AttractRepel/_5_13_AttractRepel.pde deleted file mode 100644 index 7d4c3362f..000000000 --- a/java/examples/Books/Nature of Code/chp5_physicslibraries/toxiclibs/NOC_5_13_AttractRepel/_5_13_AttractRepel.pde +++ /dev/null @@ -1,41 +0,0 @@ -import toxi.geom.*; -import toxi.physics2d.*; -import toxi.physics2d.behaviors.*; - -ArrayList particles; -Attractor attractor; - -VerletPhysics2D physics; - -void setup () { - size (800, 200); - smooth(); - physics = new VerletPhysics2D (); - physics.setDrag (0.01); - - particles = new ArrayList(); - for (int i = 0; i < 50; i++) { - particles.add(new Particle(new Vec2D(random(width),random(height)))); - } - - attractor = new Attractor(new Vec2D(width/2,height/2)); -} - - -void draw () { - background (255); - physics.update (); - - attractor.display(); - for (Particle p: particles) { - p.display(); - } - - if (mousePressed) { - attractor.lock(); - attractor.set(mouseX,mouseY); - } else { - attractor.unlock(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/Cohesion/Cohesion.pde b/java/examples/Books/Nature of Code/chp6_agents/Cohesion/Cohesion.pde deleted file mode 100644 index 976fb2308..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/Cohesion/Cohesion.pde +++ /dev/null @@ -1,49 +0,0 @@ -// Separation -// Daniel Shiffman -// The Nature of Code, 2011 - -// Via Reynolds: http://www.red3d.com/cwr/steer/ - -// A list of vehicles -ArrayList vehicles; - -void setup() { - size(640,360); - smooth(); - - // We are now making random vehicles and storing them in an ArrayList - vehicles = new ArrayList(); - for (int i = 0; i < 100; i++) { - vehicles.add(new Vehicle(random(width),random(height))); - } -} - -void draw() { - background(255); - - for (Vehicle v : vehicles) { - // Path following and separation are worked on in this function - v.cohesion(vehicles); - // Call the generic run method (update, borders, display, etc.) - v.update(); - v.borders(); - v.display(); - } - - // Instructions - fill(0); - text("Drag the mouse to generate new vehicles.",10,height-16); -} - - -void mouseDragged() { - vehicles.add(new Vehicle(mouseX,mouseY)); - - if (vehicles.size() > 200) { - vehicles.remove(0); - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/Cohesion/Vehicle.pde b/java/examples/Books/Nature of Code/chp6_agents/Cohesion/Vehicle.pde deleted file mode 100644 index bbd8719a9..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/Cohesion/Vehicle.pde +++ /dev/null @@ -1,99 +0,0 @@ -// Separation -// Daniel Shiffman -// The Nature of Code, 2011 - -// Vehicle class - -class Vehicle { - - // All the usual stuff - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - // Constructor initialize all values - Vehicle(float x, float y) { - location = new PVector(x, y); - r = 12; - maxspeed = 3; - maxforce = 0.2; - acceleration = new PVector(0, 0); - velocity = new PVector(0, 0); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - // Separation - // Method checks for nearby vehicles and steers away - void cohesion (ArrayList vehicles) { - float desiredseparation = r*2; - PVector sum = new PVector(); - int count = 0; - // For every boid in the system, check if it's too close - for (Vehicle other : vehicles) { - float d = PVector.dist(location, other.location); - // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) - if (d > desiredseparation) { - // Calculate vector pointing away from neighbor - PVector diff = PVector.sub(location, other.location); - diff.normalize(); - diff.mult(-d); // Weight by distance - sum.add(diff); - count++; // Keep track of how many - } - } - // Average -- divide by how many - if (count > 0) { - sum.div(count); - // Our desired vector is the average scaled to maximum speed - sum.normalize(); - sum.mult(maxspeed); - // Implement Reynolds: Steering = Desired - Velocity - PVector steer = PVector.sub(sum, velocity); - steer.limit(maxforce); - applyForce(steer); - } - } - - - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - } - - void display() { - fill(175); - stroke(0); - pushMatrix(); - translate(location.x, location.y); - ellipse(0, 0, r, r); - popMatrix(); - } - - // Wraparound - void borders() { - if (location.x < -r) location.x = width+r; - if (location.y < -r) location.y = height+r; - if (location.x > width+r) location.x = -r; - if (location.y > height+r) location.y = -r; - } -} - - - - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/CrowdPathFollowing.pde b/java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/CrowdPathFollowing.pde deleted file mode 100644 index d8281dd00..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/CrowdPathFollowing.pde +++ /dev/null @@ -1,76 +0,0 @@ -// Crowd Path Following -// Daniel Shiffman -// The Nature of Code, Spring 2009 - -// Via Reynolds: http://www.red3d.com/cwr/steer/CrowdPath.html - -// Using this variable to decide whether to draw all the stuff -boolean debug = false; - - -// A path object (series of connected points) -Path path; - -// Two vehicles -ArrayList vehicles; - -void setup() { - size(640,360); - smooth(); - // Call a function to generate new Path object - newPath(); - - // We are now making random vehicles and storing them in an ArrayList - vehicles = new ArrayList(); - for (int i = 0; i < 120; i++) { - newVehicle(random(width),random(height)); - } -} - -void draw() { - background(255); - // Display the path - path.display(); - - for (Vehicle v : vehicles) { - // Path following and separation are worked on in this function - v.applyBehaviors(vehicles,path); - // Call the generic run method (update, borders, display, etc.) - v.run(); - } - - // Instructions - fill(0); - text("Hit 'd' to toggle debugging lines. Click the mouse to generate new vehicles.",10,height-16); -} - -void newPath() { - // A path is a series of connected points - // A more sophisticated path might be a curve - path = new Path(); - float offset = 60; - path.addPoint(offset,offset); - path.addPoint(width-offset,offset); - path.addPoint(width-offset,height-offset); - path.addPoint(width/2,height-offset*3); - path.addPoint(offset,height-offset); -} - -void newVehicle(float x, float y) { - float maxspeed = random(2,4); - float maxforce = 0.3; - vehicles.add(new Vehicle(new PVector(x,y),maxspeed,maxforce)); -} - -void keyPressed() { - if (key == 'd') { - debug = !debug; - } -} - -void mousePressed() { - newVehicle(mouseX,mouseY); -} - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/Path.pde b/java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/Path.pde deleted file mode 100644 index d6ea21a57..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/Path.pde +++ /dev/null @@ -1,50 +0,0 @@ -// Path Following -// Daniel Shiffman -// The Nature of Code - -class Path { - - // A Path is an arraylist of points (PVector objects) - ArrayList points; - // A path has a radius, i.e how far is it ok for the boid to wander off - float radius; - - Path() { - // Arbitrary radius of 20 - radius = 20; - points = new ArrayList(); - } - - // Add a point to the path - void addPoint(float x, float y) { - PVector point = new PVector(x, y); - points.add(point); - } - - // Draw the path - void display() { - strokeJoin(ROUND); - - // Draw thick line for radius - stroke(175); - strokeWeight(radius*2); - noFill(); - beginShape(); - for (PVector v : points) { - vertex(v.x, v.y); - } - endShape(CLOSE); - // Draw thin line for center of path - stroke(0); - strokeWeight(1); - noFill(); - beginShape(); - for (PVector v : points) { - vertex(v.x, v.y); - } - endShape(CLOSE); - } -} - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/Vehicle.pde b/java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/Vehicle.pde deleted file mode 100644 index be7811b49..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/Vehicle.pde +++ /dev/null @@ -1,239 +0,0 @@ -// Path Following -// Daniel Shiffman -// The Nature of Code, Spring 2009 - -// Vehicle class - -class Vehicle { - - // All the usual stuff - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - // Constructor initialize all values - Vehicle( PVector l, float ms, float mf) { - location = l.get(); - r = 12; - maxspeed = ms; - maxforce = mf; - acceleration = new PVector(0, 0); - velocity = new PVector(maxspeed, 0); - } - - // A function to deal with path following and separation - void applyBehaviors(ArrayList vehicles, Path path) { - // Follow path force - PVector f = follow(path); - // Separate from other boids force - PVector s = separate(vehicles); - // Arbitrary weighting - f.mult(3); - s.mult(1); - // Accumulate in acceleration - applyForce(f); - applyForce(s); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - - - // Main "run" function - public void run() { - update(); - borders(); - render(); - } - - - // This function implements Craig Reynolds' path following algorithm - // http://www.red3d.com/cwr/steer/PathFollow.html - PVector follow(Path p) { - - // Predict location 25 (arbitrary choice) frames ahead - PVector predict = velocity.get(); - predict.normalize(); - predict.mult(25); - PVector predictLoc = PVector.add(location, predict); - - // Now we must find the normal to the path from the predicted location - // We look at the normal for each line segment and pick out the closest one - PVector normal = null; - PVector target = null; - float worldRecord = 1000000; // Start with a very high worldRecord distance that can easily be beaten - - // Loop through all points of the path - for (int i = 0; i < p.points.size(); i++) { - - // Look at a line segment - PVector a = p.points.get(i); - PVector b = p.points.get((i+1)%p.points.size()); // Note Path has to wraparound - - // Get the normal point to that line - PVector normalPoint = getNormalPoint(predictLoc, a, b); - - // Check if normal is on line segment - PVector dir = PVector.sub(b, a); - // If it's not within the line segment, consider the normal to just be the end of the line segment (point b) - //if (da + db > line.mag()+1) { - if (normalPoint.x < min(a.x,b.x) || normalPoint.x > max(a.x,b.x) || normalPoint.y < min(a.y,b.y) || normalPoint.y > max(a.y,b.y)) { - normalPoint = b.get(); - // If we're at the end we really want the next line segment for looking ahead - a = p.points.get((i+1)%p.points.size()); - b = p.points.get((i+2)%p.points.size()); // Path wraps around - dir = PVector.sub(b, a); - } - - // How far away are we from the path? - float d = PVector.dist(predictLoc, normalPoint); - // Did we beat the worldRecord and find the closest line segment? - if (d < worldRecord) { - worldRecord = d; - normal = normalPoint; - - // Look at the direction of the line segment so we can seek a little bit ahead of the normal - dir.normalize(); - // This is an oversimplification - // Should be based on distance to path & velocity - dir.mult(25); - target = normal.get(); - target.add(dir); - - } - } - - // Draw the debugging stuff - if (debug) { - // Draw predicted future location - stroke(0); - fill(0); - line(location.x, location.y, predictLoc.x, predictLoc.y); - ellipse(predictLoc.x, predictLoc.y, 4, 4); - - // Draw normal location - stroke(0); - fill(0); - ellipse(normal.x, normal.y, 4, 4); - // Draw actual target (red if steering towards it) - line(predictLoc.x, predictLoc.y, target.x, target.y); - if (worldRecord > p.radius) fill(255, 0, 0); - noStroke(); - ellipse(target.x, target.y, 8, 8); - } - - // Only if the distance is greater than the path's radius do we bother to steer - if (worldRecord > p.radius) { - return seek(target); - } - else { - return new PVector(0, 0); - } - } - - - // A function to get the normal point from a point (p) to a line segment (a-b) - // This function could be optimized to make fewer new Vector objects - PVector getNormalPoint(PVector p, PVector a, PVector b) { - // Vector from a to p - PVector ap = PVector.sub(p, a); - // Vector from a to b - PVector ab = PVector.sub(b, a); - ab.normalize(); // Normalize the line - // Project vector "diff" onto line by using the dot product - ab.mult(ap.dot(ab)); - PVector normalPoint = PVector.add(a, ab); - return normalPoint; - } - - // Separation - // Method checks for nearby boids and steers away - PVector separate (ArrayList boids) { - float desiredseparation = r*2; - PVector steer = new PVector(0, 0, 0); - int count = 0; - // For every boid in the system, check if it's too close - for (int i = 0 ; i < boids.size(); i++) { - Vehicle other = (Vehicle) boids.get(i); - float d = PVector.dist(location, other.location); - // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) - if ((d > 0) && (d < desiredseparation)) { - // Calculate vector pointing away from neighbor - PVector diff = PVector.sub(location, other.location); - diff.normalize(); - diff.div(d); // Weight by distance - steer.add(diff); - count++; // Keep track of how many - } - } - // Average -- divide by how many - if (count > 0) { - steer.div((float)count); - } - - // As long as the vector is greater than 0 - if (steer.mag() > 0) { - // Implement Reynolds: Steering = Desired - Velocity - steer.normalize(); - steer.mult(maxspeed); - steer.sub(velocity); - steer.limit(maxforce); - } - return steer; - } - - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - } - - // A method that calculates and applies a steering force towards a target - // STEER = DESIRED MINUS VELOCITY - PVector seek(PVector target) { - PVector desired = PVector.sub(target, location); // A vector pointing from the location to the target - - // Normalize desired and scale to maximum speed - desired.normalize(); - desired.mult(maxspeed); - // Steering = Desired minus Velocationity - PVector steer = PVector.sub(desired, velocity); - steer.limit(maxforce); // Limit to maximum steering force - - return steer; - } - - - void render() { - // Simpler boid is just a circle - fill(75); - stroke(0); - pushMatrix(); - translate(location.x, location.y); - ellipse(0, 0, r, r); - popMatrix(); - } - - // Wraparound - void borders() { - if (location.x < -r) location.x = width+r; - //if (location.y < -r) location.y = height+r; - if (location.x > width+r) location.x = -r; - //if (location.y > height+r) location.y = -r; - } -} - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/applet_js/CrowdPathFollowing.pde b/java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/applet_js/CrowdPathFollowing.pde deleted file mode 100644 index 607ab1009..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/applet_js/CrowdPathFollowing.pde +++ /dev/null @@ -1,365 +0,0 @@ -// Crowd Path Following -// Daniel Shiffman -// The Nature of Code, Spring 2009 - -// Via Reynolds: http://www.red3d.com/cwr/steer/CrowdPath.html - -// Using this variable to decide whether to draw all the stuff -boolean debug = false; - - -// A path object (series of connected points) -Path path; - -// Two vehicles -ArrayList vehicles; - -void setup() { - size(640,360); - smooth(); - - // Call a function to generate new Path object - newPath(); - - // We are now making random vehicles and storing them in an ArrayList - vehicles = new ArrayList(); - for (int i = 0; i < 120; i++) { - newVehicle(random(width),random(height)); - } -} - -void draw() { - background(255); - // Display the path - path.display(); - - for (Vehicle v : vehicles) { - // Path following and separation are worked on in this function - v.applyBehaviors(vehicles,path); - // Call the generic run method (update, borders, display, etc.) - v.run(); - } - - // Instructions - fill(0); - text("Hit 'd' to toggle debugging lines. Click the mouse to generate new vehicles.",10,height-16); -} - -void newPath() { - // A path is a series of connected points - // A more sophisticated path might be a curve - path = new Path(); - float offset = 60; - path.addPoint(offset,offset); - path.addPoint(width-offset,offset); - path.addPoint(width-offset,height-offset); - path.addPoint(width/2,height-offset*3); - path.addPoint(offset,height-offset); -} - -void newVehicle(float x, float y) { - float maxspeed = random(2,4); - float maxforce = 0.3; - vehicles.add(new Vehicle(new PVector(x,y),maxspeed,maxforce)); -} - -void keyPressed() { - if (key == 'd') { - debug = !debug; - } -} - -void mousePressed() { - newVehicle(mouseX,mouseY); -} - - - -// Path Following -// Daniel Shiffman -// The Nature of Code - -class Path { - - // A Path is an arraylist of points (PVector objects) - ArrayList points; - // A path has a radius, i.e how far is it ok for the boid to wander off - float radius; - - Path() { - // Arbitrary radius of 20 - radius = 20; - points = new ArrayList(); - } - - // Add a point to the path - void addPoint(float x, float y) { - PVector point = new PVector(x, y); - points.add(point); - } - - // Draw the path - void display() { - // Draw thick line for radius - stroke(175); - strokeWeight(radius*2); - noFill(); - beginShape(); - for (PVector v : points) { - vertex(v.x, v.y); - } - endShape(CLOSE); - // Draw thin line for center of path - stroke(0); - strokeWeight(1); - noFill(); - beginShape(); - for (PVector v : points) { - vertex(v.x, v.y); - } - endShape(CLOSE); - } -} - - - -// Path Following -// Daniel Shiffman -// The Nature of Code, Spring 2009 - -// Vehicle class - -class Vehicle { - - // All the usual stuff - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - // Constructor initialize all values - Vehicle( PVector l, float ms, float mf) { - location = l.get(); - r = 12; - maxspeed = ms; - maxforce = mf; - acceleration = new PVector(0, 0); - velocity = new PVector(maxspeed, 0); - } - - // A function to deal with path following and separation - void applyBehaviors(ArrayList vehicles, Path path) { - // Follow path force - PVector f = follow(path); - // Separate from other boids force - PVector s = separate(vehicles); - // Arbitrary weighting - f.mult(3); - s.mult(1); - // Accumulate in acceleration - applyForce(f); - applyForce(s); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - - - // Main "run" function - public void run() { - update(); - borders(); - render(); - } - - - // This function implements Craig Reynolds' path following algorithm - // http://www.red3d.com/cwr/steer/PathFollow.html - PVector follow(Path p) { - - // Predict location 25 (arbitrary choice) frames ahead - PVector predict = velocity.get(); - predict.normalize(); - predict.mult(25); - PVector predictLoc = PVector.add(location, predict); - - // Now we must find the normal to the path from the predicted location - // We look at the normal for each line segment and pick out the closest one - PVector normal = null; - PVector target = null; - float worldRecord = 1000000; // Start with a very high worldRecord distance that can easily be beaten - - // Loop through all points of the path - for (int i = 0; i < p.points.size(); i++) { - - // Look at a line segment - PVector a = p.points.get(i); - PVector b = p.points.get((i+1)%p.points.size()); // Note Path has to wraparound - - // Get the normal point to that line - PVector normalPoint = getNormalPoint(predictLoc, a, b); - - // Check if normal is on line segment - PVector dir = PVector.sub(b, a); - // If it's not within the line segment, consider the normal to just be the end of the line segment (point b) - //if (da + db > line.mag()+1) { - if (normalPoint.x < min(a.x,b.x) || normalPoint.x > max(a.x,b.x) || normalPoint.y < min(a.y,b.y) || normalPoint.y > max(a.y,b.y)) { - normalPoint = b.get(); - // If we're at the end we really want the next line segment for looking ahead - a = p.points.get((i+1)%p.points.size()); - b = p.points.get((i+2)%p.points.size()); // Path wraps around - dir = PVector.sub(b, a); - } - - // How far away are we from the path? - float d = PVector.dist(predictLoc, normalPoint); - // Did we beat the worldRecord and find the closest line segment? - if (d < worldRecord) { - worldRecord = d; - normal = normalPoint; - - // Look at the direction of the line segment so we can seek a little bit ahead of the normal - dir.normalize(); - // This is an oversimplification - // Should be based on distance to path & velocity - dir.mult(25); - target = normal.get(); - target.add(dir); - - } - } - - // Draw the debugging stuff - if (debug) { - // Draw predicted future location - stroke(0); - fill(0); - line(location.x, location.y, predictLoc.x, predictLoc.y); - ellipse(predictLoc.x, predictLoc.y, 4, 4); - - // Draw normal location - stroke(0); - fill(0); - ellipse(normal.x, normal.y, 4, 4); - // Draw actual target (red if steering towards it) - line(predictLoc.x, predictLoc.y, target.x, target.y); - if (worldRecord > p.radius) fill(255, 0, 0); - noStroke(); - ellipse(target.x, target.y, 8, 8); - } - - // Only if the distance is greater than the path's radius do we bother to steer - if (worldRecord > p.radius) { - return seek(target); - } - else { - return new PVector(0, 0); - } - } - - - // A function to get the normal point from a point (p) to a line segment (a-b) - // This function could be optimized to make fewer new Vector objects - PVector getNormalPoint(PVector p, PVector a, PVector b) { - // Vector from a to p - PVector ap = PVector.sub(p, a); - // Vector from a to b - PVector ab = PVector.sub(b, a); - ab.normalize(); // Normalize the line - // Project vector "diff" onto line by using the dot product - ab.mult(ap.dot(ab)); - PVector normalPoint = PVector.add(a, ab); - return normalPoint; - } - - // Separation - // Method checks for nearby boids and steers away - PVector separate (ArrayList boids) { - float desiredseparation = r*2; - PVector steer = new PVector(0, 0, 0); - int count = 0; - // For every boid in the system, check if it's too close - for (int i = 0 ; i < boids.size(); i++) { - Vehicle other = (Vehicle) boids.get(i); - float d = PVector.dist(location, other.location); - // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) - if ((d > 0) && (d < desiredseparation)) { - // Calculate vector pointing away from neighbor - PVector diff = PVector.sub(location, other.location); - diff.normalize(); - diff.div(d); // Weight by distance - steer.add(diff); - count++; // Keep track of how many - } - } - // Average -- divide by how many - if (count > 0) { - steer.div((float)count); - } - - // As long as the vector is greater than 0 - if (steer.mag() > 0) { - // Implement Reynolds: Steering = Desired - Velocity - steer.normalize(); - steer.mult(maxspeed); - steer.sub(velocity); - steer.limit(maxforce); - } - return steer; - } - - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - } - - // A method that calculates and applies a steering force towards a target - // STEER = DESIRED MINUS VELOCITY - PVector seek(PVector target) { - PVector desired = PVector.sub(target, location); // A vector pointing from the location to the target - - // Normalize desired and scale to maximum speed - desired.normalize(); - desired.mult(maxspeed); - // Steering = Desired minus Velocationity - PVector steer = PVector.sub(desired, velocity); - steer.limit(maxforce); // Limit to maximum steering force - - return steer; - } - - - void render() { - // Simpler boid is just a circle - fill(75); - stroke(0); - pushMatrix(); - translate(location.x, location.y); - ellipse(0, 0, r, r); - popMatrix(); - } - - // Wraparound - void borders() { - if (location.x < -r) location.x = width+r; - //if (location.y < -r) location.y = height+r; - if (location.x > width+r) location.x = -r; - //if (location.y > height+r) location.y = -r; - } -} - - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/applet_js/processing.js b/java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/applet_js/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/applet_js/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/sketch.properties b/java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/sketch.properties deleted file mode 100644 index 28faa5897..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/CrowdPathFollowing/sketch.properties +++ /dev/null @@ -1 +0,0 @@ -mode=Standard diff --git a/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_04_Wander/Ex_6_04_Wander.pde b/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_04_Wander/Ex_6_04_Wander.pde deleted file mode 100644 index 734b1db00..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_04_Wander/Ex_6_04_Wander.pde +++ /dev/null @@ -1,30 +0,0 @@ -// Wander -// Daniel Shiffman -// The Nature of Code - -// Demonstration of Craig Reynolds' "Wandering" behavior -// See: http://www.red3d.com/cwr/ - -// Click mouse to turn on and off rendering of the wander circle - - -Vehicle wanderer; -boolean debug = true; - -void setup() { - size(740,200); - wanderer = new Vehicle(width/2,height/2); - smooth(); -} - -void draw() { - background(255); - wanderer.wander(); - wanderer.run(); -} - -void mousePressed() { - debug = !debug; -} - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_04_Wander/Vehicle.pde b/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_04_Wander/Vehicle.pde deleted file mode 100644 index 87a836746..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_04_Wander/Vehicle.pde +++ /dev/null @@ -1,123 +0,0 @@ -// Wander -// Daniel Shiffman -// The Nature of Code - -// The "Vehicle" class (for wandering) - -class Vehicle { - - PVector location; - PVector velocity; - PVector acceleration; - float r; - float wandertheta; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - Vehicle(float x, float y) { - acceleration = new PVector(0,0); - velocity = new PVector(0,0); - location = new PVector(x,y); - r = 6; - wandertheta = 0; - maxspeed = 2; - maxforce = 0.05; - } - - void run() { - update(); - borders(); - display(); - } - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - } - - void wander() { - float wanderR = 25; // Radius for our "wander circle" - float wanderD = 80; // Distance for our "wander circle" - float change = 0.3; - wandertheta += random(-change,change); // Randomly change wander theta - - // Now we have to calculate the new location to steer towards on the wander circle - PVector circleloc = velocity.get(); // Start with velocity - circleloc.normalize(); // Normalize to get heading - circleloc.mult(wanderD); // Multiply by distance - circleloc.add(location); // Make it relative to boid's location - - float h = velocity.heading2D(); // We need to know the heading to offset wandertheta - - PVector circleOffSet = new PVector(wanderR*cos(wandertheta+h),wanderR*sin(wandertheta+h)); - PVector target = PVector.add(circleloc,circleOffSet); - seek(target); - - // Render wandering circle, etc. - if (debug) drawWanderStuff(location,circleloc,target,wanderR); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - - // A method that calculates and applies a steering force towards a target - // STEER = DESIRED MINUS VELOCITY - void seek(PVector target) { - PVector desired = PVector.sub(target,location); // A vector pointing from the location to the target - - // Normalize desired and scale to maximum speed - desired.normalize(); - desired.mult(maxspeed); - // Steering = Desired minus Velocity - PVector steer = PVector.sub(desired,velocity); - steer.limit(maxforce); // Limit to maximum steering force - - applyForce(steer); - } - - void display() { - // Draw a triangle rotated in the direction of velocity - float theta = velocity.heading2D() + radians(90); - fill(127); - stroke(0); - pushMatrix(); - translate(location.x,location.y); - rotate(theta); - beginShape(TRIANGLES); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(); - popMatrix(); - } - - // Wraparound - void borders() { - if (location.x < -r) location.x = width+r; - if (location.y < -r) location.y = height+r; - if (location.x > width+r) location.x = -r; - if (location.y > height+r) location.y = -r; - } -} - - -// A method just to draw the circle associated with wandering -void drawWanderStuff(PVector location, PVector circle, PVector target, float rad) { - stroke(0); - noFill(); - ellipseMode(CENTER); - ellipse(circle.x,circle.y,rad*2,rad*2); - ellipse(target.x,target.y,4,4); - line(location.x,location.y,circle.x,circle.y); - line(circle.x,circle.y,target.x,target.y); -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_09_AngleBetween/Ex_6_09_AngleBetween.pde b/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_09_AngleBetween/Ex_6_09_AngleBetween.pde deleted file mode 100644 index fb9e3b9ce..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_09_AngleBetween/Ex_6_09_AngleBetween.pde +++ /dev/null @@ -1,54 +0,0 @@ -// Angle Between Two Vectors -// Daniel Shiffman -// The Nature of Code - -// Using the dot product to compute the angle between two vectors - -void setup() { - size(383, 200); - smooth(); -} - -void draw() { - background(255); - - // A "vector" (really a point) to store the mouse location and screen center location - PVector mouseLoc = new PVector(mouseX, mouseY); - PVector centerLoc = new PVector(width/2, height/2); - - // Aha, a vector to store the displacement between the mouse and center - PVector v = PVector.sub(mouseLoc, centerLoc); - v.normalize(); - v.mult(75); - - PVector xaxis = new PVector(75, 0); - // Render the vector - drawVector(v, centerLoc, 1.0); - drawVector(xaxis, centerLoc, 1.0); - - - float theta = PVector.angleBetween(v, xaxis); - - fill(0); - text(int(degrees(theta)) + " degrees\n" + theta + " radians", 10, 160); -} - -// Renders a vector object 'v' as an arrow and a location 'loc' -void drawVector(PVector v, PVector loc, float scayl) { - pushMatrix(); - float arrowsize = 6; - // Translate to location to render vector - translate(loc.x, loc.y); - stroke(0); - strokeWeight(2); - // Call vector heading function to get direction (pointing up is a heading of 0) - rotate(v.heading2D()); - // Calculate length of vector & scale it to be bigger or smaller if necessary - float len = v.mag()*scayl; - // Draw three lines to make an arrow - line(0, 0, len, 0); - line(len, 0, len-arrowsize, +arrowsize/2); - line(len, 0, len-arrowsize, -arrowsize/2); - popMatrix(); -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/Ex_6_13_CrowdPathFollowing.pde b/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/Ex_6_13_CrowdPathFollowing.pde deleted file mode 100644 index 8815cbb25..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/Ex_6_13_CrowdPathFollowing.pde +++ /dev/null @@ -1,77 +0,0 @@ -// Crowd Path Following -// Daniel Shiffman -// The Nature of Code, Spring 2009 - -// Via Reynolds: http://www.red3d.com/cwr/steer/CrowdPath.html - -// Using this variable to decide whether to draw all the stuff -boolean debug = false; - - -// A path object (series of connected points) -Path path; - -// Two vehicles -ArrayList vehicles; - -void setup() { - size(720,200); - smooth(); - // Call a function to generate new Path object - newPath(); - - // We are now making random vehicles and storing them in an ArrayList - vehicles = new ArrayList(); - for (int i = 0; i < 120; i++) { - newVehicle(random(width),random(height)); - } -} - -void draw() { - background(255); - // Display the path - path.display(); - - for (Vehicle v : vehicles) { - // Path following and separation are worked on in this function - v.applyBehaviors(vehicles,path); - // Call the generic run method (update, borders, display, etc.) - v.run(); - } - - // Instructions - fill(0); - textAlign(CENTER); - text("Hit 'd' to toggle debugging lines.\nClick the mouse to generate new vehicles.",width/2,height-20); -} - -void newPath() { - // A path is a series of connected points - // A more sophisticated path might be a curve - path = new Path(); - float offset = 30; - path.addPoint(offset,offset); - path.addPoint(width-offset,offset); - path.addPoint(width-offset,height-offset); - path.addPoint(width/2,height-offset*3); - path.addPoint(offset,height-offset); -} - -void newVehicle(float x, float y) { - float maxspeed = random(2,4); - float maxforce = 0.3; - vehicles.add(new Vehicle(new PVector(x,y),maxspeed,maxforce)); -} - -void keyPressed() { - if (key == 'd') { - debug = !debug; - } -} - -void mousePressed() { - newVehicle(mouseX,mouseY); -} - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/Path.pde b/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/Path.pde deleted file mode 100644 index d6ea21a57..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/Path.pde +++ /dev/null @@ -1,50 +0,0 @@ -// Path Following -// Daniel Shiffman -// The Nature of Code - -class Path { - - // A Path is an arraylist of points (PVector objects) - ArrayList points; - // A path has a radius, i.e how far is it ok for the boid to wander off - float radius; - - Path() { - // Arbitrary radius of 20 - radius = 20; - points = new ArrayList(); - } - - // Add a point to the path - void addPoint(float x, float y) { - PVector point = new PVector(x, y); - points.add(point); - } - - // Draw the path - void display() { - strokeJoin(ROUND); - - // Draw thick line for radius - stroke(175); - strokeWeight(radius*2); - noFill(); - beginShape(); - for (PVector v : points) { - vertex(v.x, v.y); - } - endShape(CLOSE); - // Draw thin line for center of path - stroke(0); - strokeWeight(1); - noFill(); - beginShape(); - for (PVector v : points) { - vertex(v.x, v.y); - } - endShape(CLOSE); - } -} - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/Vehicle.pde b/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/Vehicle.pde deleted file mode 100644 index be7811b49..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/Vehicle.pde +++ /dev/null @@ -1,239 +0,0 @@ -// Path Following -// Daniel Shiffman -// The Nature of Code, Spring 2009 - -// Vehicle class - -class Vehicle { - - // All the usual stuff - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - // Constructor initialize all values - Vehicle( PVector l, float ms, float mf) { - location = l.get(); - r = 12; - maxspeed = ms; - maxforce = mf; - acceleration = new PVector(0, 0); - velocity = new PVector(maxspeed, 0); - } - - // A function to deal with path following and separation - void applyBehaviors(ArrayList vehicles, Path path) { - // Follow path force - PVector f = follow(path); - // Separate from other boids force - PVector s = separate(vehicles); - // Arbitrary weighting - f.mult(3); - s.mult(1); - // Accumulate in acceleration - applyForce(f); - applyForce(s); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - - - // Main "run" function - public void run() { - update(); - borders(); - render(); - } - - - // This function implements Craig Reynolds' path following algorithm - // http://www.red3d.com/cwr/steer/PathFollow.html - PVector follow(Path p) { - - // Predict location 25 (arbitrary choice) frames ahead - PVector predict = velocity.get(); - predict.normalize(); - predict.mult(25); - PVector predictLoc = PVector.add(location, predict); - - // Now we must find the normal to the path from the predicted location - // We look at the normal for each line segment and pick out the closest one - PVector normal = null; - PVector target = null; - float worldRecord = 1000000; // Start with a very high worldRecord distance that can easily be beaten - - // Loop through all points of the path - for (int i = 0; i < p.points.size(); i++) { - - // Look at a line segment - PVector a = p.points.get(i); - PVector b = p.points.get((i+1)%p.points.size()); // Note Path has to wraparound - - // Get the normal point to that line - PVector normalPoint = getNormalPoint(predictLoc, a, b); - - // Check if normal is on line segment - PVector dir = PVector.sub(b, a); - // If it's not within the line segment, consider the normal to just be the end of the line segment (point b) - //if (da + db > line.mag()+1) { - if (normalPoint.x < min(a.x,b.x) || normalPoint.x > max(a.x,b.x) || normalPoint.y < min(a.y,b.y) || normalPoint.y > max(a.y,b.y)) { - normalPoint = b.get(); - // If we're at the end we really want the next line segment for looking ahead - a = p.points.get((i+1)%p.points.size()); - b = p.points.get((i+2)%p.points.size()); // Path wraps around - dir = PVector.sub(b, a); - } - - // How far away are we from the path? - float d = PVector.dist(predictLoc, normalPoint); - // Did we beat the worldRecord and find the closest line segment? - if (d < worldRecord) { - worldRecord = d; - normal = normalPoint; - - // Look at the direction of the line segment so we can seek a little bit ahead of the normal - dir.normalize(); - // This is an oversimplification - // Should be based on distance to path & velocity - dir.mult(25); - target = normal.get(); - target.add(dir); - - } - } - - // Draw the debugging stuff - if (debug) { - // Draw predicted future location - stroke(0); - fill(0); - line(location.x, location.y, predictLoc.x, predictLoc.y); - ellipse(predictLoc.x, predictLoc.y, 4, 4); - - // Draw normal location - stroke(0); - fill(0); - ellipse(normal.x, normal.y, 4, 4); - // Draw actual target (red if steering towards it) - line(predictLoc.x, predictLoc.y, target.x, target.y); - if (worldRecord > p.radius) fill(255, 0, 0); - noStroke(); - ellipse(target.x, target.y, 8, 8); - } - - // Only if the distance is greater than the path's radius do we bother to steer - if (worldRecord > p.radius) { - return seek(target); - } - else { - return new PVector(0, 0); - } - } - - - // A function to get the normal point from a point (p) to a line segment (a-b) - // This function could be optimized to make fewer new Vector objects - PVector getNormalPoint(PVector p, PVector a, PVector b) { - // Vector from a to p - PVector ap = PVector.sub(p, a); - // Vector from a to b - PVector ab = PVector.sub(b, a); - ab.normalize(); // Normalize the line - // Project vector "diff" onto line by using the dot product - ab.mult(ap.dot(ab)); - PVector normalPoint = PVector.add(a, ab); - return normalPoint; - } - - // Separation - // Method checks for nearby boids and steers away - PVector separate (ArrayList boids) { - float desiredseparation = r*2; - PVector steer = new PVector(0, 0, 0); - int count = 0; - // For every boid in the system, check if it's too close - for (int i = 0 ; i < boids.size(); i++) { - Vehicle other = (Vehicle) boids.get(i); - float d = PVector.dist(location, other.location); - // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) - if ((d > 0) && (d < desiredseparation)) { - // Calculate vector pointing away from neighbor - PVector diff = PVector.sub(location, other.location); - diff.normalize(); - diff.div(d); // Weight by distance - steer.add(diff); - count++; // Keep track of how many - } - } - // Average -- divide by how many - if (count > 0) { - steer.div((float)count); - } - - // As long as the vector is greater than 0 - if (steer.mag() > 0) { - // Implement Reynolds: Steering = Desired - Velocity - steer.normalize(); - steer.mult(maxspeed); - steer.sub(velocity); - steer.limit(maxforce); - } - return steer; - } - - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - } - - // A method that calculates and applies a steering force towards a target - // STEER = DESIRED MINUS VELOCITY - PVector seek(PVector target) { - PVector desired = PVector.sub(target, location); // A vector pointing from the location to the target - - // Normalize desired and scale to maximum speed - desired.normalize(); - desired.mult(maxspeed); - // Steering = Desired minus Velocationity - PVector steer = PVector.sub(desired, velocity); - steer.limit(maxforce); // Limit to maximum steering force - - return steer; - } - - - void render() { - // Simpler boid is just a circle - fill(75); - stroke(0); - pushMatrix(); - translate(location.x, location.y); - ellipse(0, 0, r, r); - popMatrix(); - } - - // Wraparound - void borders() { - if (location.x < -r) location.x = width+r; - //if (location.y < -r) location.y = height+r; - if (location.x > width+r) location.x = -r; - //if (location.y > height+r) location.y = -r; - } -} - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/applet_js/CrowdPathFollowing.pde b/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/applet_js/CrowdPathFollowing.pde deleted file mode 100644 index 607ab1009..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/applet_js/CrowdPathFollowing.pde +++ /dev/null @@ -1,365 +0,0 @@ -// Crowd Path Following -// Daniel Shiffman -// The Nature of Code, Spring 2009 - -// Via Reynolds: http://www.red3d.com/cwr/steer/CrowdPath.html - -// Using this variable to decide whether to draw all the stuff -boolean debug = false; - - -// A path object (series of connected points) -Path path; - -// Two vehicles -ArrayList vehicles; - -void setup() { - size(640,360); - smooth(); - - // Call a function to generate new Path object - newPath(); - - // We are now making random vehicles and storing them in an ArrayList - vehicles = new ArrayList(); - for (int i = 0; i < 120; i++) { - newVehicle(random(width),random(height)); - } -} - -void draw() { - background(255); - // Display the path - path.display(); - - for (Vehicle v : vehicles) { - // Path following and separation are worked on in this function - v.applyBehaviors(vehicles,path); - // Call the generic run method (update, borders, display, etc.) - v.run(); - } - - // Instructions - fill(0); - text("Hit 'd' to toggle debugging lines. Click the mouse to generate new vehicles.",10,height-16); -} - -void newPath() { - // A path is a series of connected points - // A more sophisticated path might be a curve - path = new Path(); - float offset = 60; - path.addPoint(offset,offset); - path.addPoint(width-offset,offset); - path.addPoint(width-offset,height-offset); - path.addPoint(width/2,height-offset*3); - path.addPoint(offset,height-offset); -} - -void newVehicle(float x, float y) { - float maxspeed = random(2,4); - float maxforce = 0.3; - vehicles.add(new Vehicle(new PVector(x,y),maxspeed,maxforce)); -} - -void keyPressed() { - if (key == 'd') { - debug = !debug; - } -} - -void mousePressed() { - newVehicle(mouseX,mouseY); -} - - - -// Path Following -// Daniel Shiffman -// The Nature of Code - -class Path { - - // A Path is an arraylist of points (PVector objects) - ArrayList points; - // A path has a radius, i.e how far is it ok for the boid to wander off - float radius; - - Path() { - // Arbitrary radius of 20 - radius = 20; - points = new ArrayList(); - } - - // Add a point to the path - void addPoint(float x, float y) { - PVector point = new PVector(x, y); - points.add(point); - } - - // Draw the path - void display() { - // Draw thick line for radius - stroke(175); - strokeWeight(radius*2); - noFill(); - beginShape(); - for (PVector v : points) { - vertex(v.x, v.y); - } - endShape(CLOSE); - // Draw thin line for center of path - stroke(0); - strokeWeight(1); - noFill(); - beginShape(); - for (PVector v : points) { - vertex(v.x, v.y); - } - endShape(CLOSE); - } -} - - - -// Path Following -// Daniel Shiffman -// The Nature of Code, Spring 2009 - -// Vehicle class - -class Vehicle { - - // All the usual stuff - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - // Constructor initialize all values - Vehicle( PVector l, float ms, float mf) { - location = l.get(); - r = 12; - maxspeed = ms; - maxforce = mf; - acceleration = new PVector(0, 0); - velocity = new PVector(maxspeed, 0); - } - - // A function to deal with path following and separation - void applyBehaviors(ArrayList vehicles, Path path) { - // Follow path force - PVector f = follow(path); - // Separate from other boids force - PVector s = separate(vehicles); - // Arbitrary weighting - f.mult(3); - s.mult(1); - // Accumulate in acceleration - applyForce(f); - applyForce(s); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - - - // Main "run" function - public void run() { - update(); - borders(); - render(); - } - - - // This function implements Craig Reynolds' path following algorithm - // http://www.red3d.com/cwr/steer/PathFollow.html - PVector follow(Path p) { - - // Predict location 25 (arbitrary choice) frames ahead - PVector predict = velocity.get(); - predict.normalize(); - predict.mult(25); - PVector predictLoc = PVector.add(location, predict); - - // Now we must find the normal to the path from the predicted location - // We look at the normal for each line segment and pick out the closest one - PVector normal = null; - PVector target = null; - float worldRecord = 1000000; // Start with a very high worldRecord distance that can easily be beaten - - // Loop through all points of the path - for (int i = 0; i < p.points.size(); i++) { - - // Look at a line segment - PVector a = p.points.get(i); - PVector b = p.points.get((i+1)%p.points.size()); // Note Path has to wraparound - - // Get the normal point to that line - PVector normalPoint = getNormalPoint(predictLoc, a, b); - - // Check if normal is on line segment - PVector dir = PVector.sub(b, a); - // If it's not within the line segment, consider the normal to just be the end of the line segment (point b) - //if (da + db > line.mag()+1) { - if (normalPoint.x < min(a.x,b.x) || normalPoint.x > max(a.x,b.x) || normalPoint.y < min(a.y,b.y) || normalPoint.y > max(a.y,b.y)) { - normalPoint = b.get(); - // If we're at the end we really want the next line segment for looking ahead - a = p.points.get((i+1)%p.points.size()); - b = p.points.get((i+2)%p.points.size()); // Path wraps around - dir = PVector.sub(b, a); - } - - // How far away are we from the path? - float d = PVector.dist(predictLoc, normalPoint); - // Did we beat the worldRecord and find the closest line segment? - if (d < worldRecord) { - worldRecord = d; - normal = normalPoint; - - // Look at the direction of the line segment so we can seek a little bit ahead of the normal - dir.normalize(); - // This is an oversimplification - // Should be based on distance to path & velocity - dir.mult(25); - target = normal.get(); - target.add(dir); - - } - } - - // Draw the debugging stuff - if (debug) { - // Draw predicted future location - stroke(0); - fill(0); - line(location.x, location.y, predictLoc.x, predictLoc.y); - ellipse(predictLoc.x, predictLoc.y, 4, 4); - - // Draw normal location - stroke(0); - fill(0); - ellipse(normal.x, normal.y, 4, 4); - // Draw actual target (red if steering towards it) - line(predictLoc.x, predictLoc.y, target.x, target.y); - if (worldRecord > p.radius) fill(255, 0, 0); - noStroke(); - ellipse(target.x, target.y, 8, 8); - } - - // Only if the distance is greater than the path's radius do we bother to steer - if (worldRecord > p.radius) { - return seek(target); - } - else { - return new PVector(0, 0); - } - } - - - // A function to get the normal point from a point (p) to a line segment (a-b) - // This function could be optimized to make fewer new Vector objects - PVector getNormalPoint(PVector p, PVector a, PVector b) { - // Vector from a to p - PVector ap = PVector.sub(p, a); - // Vector from a to b - PVector ab = PVector.sub(b, a); - ab.normalize(); // Normalize the line - // Project vector "diff" onto line by using the dot product - ab.mult(ap.dot(ab)); - PVector normalPoint = PVector.add(a, ab); - return normalPoint; - } - - // Separation - // Method checks for nearby boids and steers away - PVector separate (ArrayList boids) { - float desiredseparation = r*2; - PVector steer = new PVector(0, 0, 0); - int count = 0; - // For every boid in the system, check if it's too close - for (int i = 0 ; i < boids.size(); i++) { - Vehicle other = (Vehicle) boids.get(i); - float d = PVector.dist(location, other.location); - // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) - if ((d > 0) && (d < desiredseparation)) { - // Calculate vector pointing away from neighbor - PVector diff = PVector.sub(location, other.location); - diff.normalize(); - diff.div(d); // Weight by distance - steer.add(diff); - count++; // Keep track of how many - } - } - // Average -- divide by how many - if (count > 0) { - steer.div((float)count); - } - - // As long as the vector is greater than 0 - if (steer.mag() > 0) { - // Implement Reynolds: Steering = Desired - Velocity - steer.normalize(); - steer.mult(maxspeed); - steer.sub(velocity); - steer.limit(maxforce); - } - return steer; - } - - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - } - - // A method that calculates and applies a steering force towards a target - // STEER = DESIRED MINUS VELOCITY - PVector seek(PVector target) { - PVector desired = PVector.sub(target, location); // A vector pointing from the location to the target - - // Normalize desired and scale to maximum speed - desired.normalize(); - desired.mult(maxspeed); - // Steering = Desired minus Velocationity - PVector steer = PVector.sub(desired, velocity); - steer.limit(maxforce); // Limit to maximum steering force - - return steer; - } - - - void render() { - // Simpler boid is just a circle - fill(75); - stroke(0); - pushMatrix(); - translate(location.x, location.y); - ellipse(0, 0, r, r); - popMatrix(); - } - - // Wraparound - void borders() { - if (location.x < -r) location.x = width+r; - //if (location.y < -r) location.y = height+r; - if (location.x > width+r) location.x = -r; - //if (location.y > height+r) location.y = -r; - } -} - - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/applet_js/processing.js b/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/applet_js/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/applet_js/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/sketch.properties b/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/sketch.properties deleted file mode 100644 index 28faa5897..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/Exercise_6_13_CrowdPathFollowing/sketch.properties +++ /dev/null @@ -1 +0,0 @@ -mode=Standard diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_01_Seek/Vehicle.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_01_Seek/Vehicle.pde deleted file mode 100644 index 55d5e83e9..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_01_Seek/Vehicle.pde +++ /dev/null @@ -1,74 +0,0 @@ -// Seek_Arrive -// Daniel Shiffman - -// The "Vehicle" class - -class Vehicle { - - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - Vehicle(float x, float y) { - acceleration = new PVector(0,0); - velocity = new PVector(0,-2); - location = new PVector(x,y); - r = 6; - maxspeed = 4; - maxforce = 0.1; - } - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelerationelertion to 0 each cycle - acceleration.mult(0); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - // A method that calculates a steering force towards a target - // STEER = DESIRED MINUS VELOCITY - void seek(PVector target) { - PVector desired = PVector.sub(target,location); // A vector pointing from the location to the target - - // Normalize desired and scale to maximum speed - desired.normalize(); - desired.mult(maxspeed); - // Steering = Desired minus velocity - PVector steer = PVector.sub(desired,velocity); - steer.limit(maxforce); // Limit to maximum steering force - - applyForce(steer); - } - - void display() { - // Draw a triangle rotated in the direction of velocity - float theta = velocity.heading2D() + PI/2; - fill(127); - stroke(0); - strokeWeight(1); - pushMatrix(); - translate(location.x,location.y); - rotate(theta); - beginShape(); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(CLOSE); - popMatrix(); - - - } -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_01_Seek/_6_01_Seek.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_01_Seek/_6_01_Seek.pde deleted file mode 100644 index 91534778c..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_01_Seek/_6_01_Seek.pde +++ /dev/null @@ -1,36 +0,0 @@ -// Seek_Arrive -// Daniel Shiffman -// Nature of Code, Spring 2011 - -// Two "vehicles" follow the mouse position - -// Implements Craig Reynold's autonomous steering behaviors -// One vehicle "seeks" -// One vehicle "arrives" -// See: http://www.red3d.com/cwr/ - -Vehicle v; - -void setup() { - size(800, 200); - v = new Vehicle(width/2, height/2); - smooth(); -} - -void draw() { - background(255); - - PVector mouse = new PVector(mouseX, mouseY); - - // Draw an ellipse at the mouse location - fill(200); - stroke(0); - strokeWeight(2); - ellipse(mouse.x, mouse.y, 48, 48); - - // Call the appropriate steering behaviors for our agents - v.seek(mouse); - v.update(); - v.display(); -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_01_Seek_trail/Vehicle.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_01_Seek_trail/Vehicle.pde deleted file mode 100644 index 0491c53ea..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_01_Seek_trail/Vehicle.pde +++ /dev/null @@ -1,90 +0,0 @@ -// Seek_Arrive -// Daniel Shiffman - -// The "Vehicle" class - -class Vehicle { - ArrayList history = new ArrayList(); - - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - Vehicle(float x, float y) { - acceleration = new PVector(0,0); - velocity = new PVector(0,-2); - location = new PVector(x,y); - r = 6; - maxspeed = 4; - maxforce = 0.1; - } - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelerationelertion to 0 each cycle - acceleration.mult(0); - - history.add(location.get()); - if (history.size() > 100) { - history.remove(0); - } - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - // A method that calculates a steering force towards a target - // STEER = DESIRED MINUS VELOCITY - void seek(PVector target) { - PVector desired = PVector.sub(target,location); // A vector pointing from the location to the target - - // Normalize desired and scale to maximum speed - desired.normalize(); - desired.mult(maxspeed); - // Steering = Desired minus velocity - PVector steer = PVector.sub(desired,velocity); - steer.limit(maxforce); // Limit to maximum steering force - - applyForce(steer); - } - - void display() { - beginShape(); - stroke(0); - strokeWeight(1); - noFill(); - for(PVector v: history) { - vertex(v.x,v.y); - } - endShape(); - - - // Draw a triangle rotated in the direction of velocity - float theta = velocity.heading2D() + PI/2; - fill(127); - stroke(0); - strokeWeight(1); - pushMatrix(); - translate(location.x,location.y); - rotate(theta); - beginShape(); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(CLOSE); - popMatrix(); - - - } -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_01_Seek_trail/_6_01_Seek_trail.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_01_Seek_trail/_6_01_Seek_trail.pde deleted file mode 100644 index 129a44bcc..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_01_Seek_trail/_6_01_Seek_trail.pde +++ /dev/null @@ -1,39 +0,0 @@ -// Seek_Arrive -// Daniel Shiffman -// Nature of Code, Spring 2011 - -// Two "vehicles" follow the mouse position - -// Implements Craig Reynold's autonomous steering behaviors -// One vehicle "seeks" -// One vehicle "arrives" -// See: http://www.red3d.com/cwr/ - -Vehicle v; - -void setup() { - size(800, 200); - v = new Vehicle(width/2, height/2); - smooth(); -} - -void draw() { - if (mousePressed) { - - background(255); - - PVector mouse = new PVector(mouseX, mouseY); - - // Draw an ellipse at the mouse location - fill(200); - stroke(0); - strokeWeight(2); - ellipse(mouse.x, mouse.y, 48, 48); - - // Call the appropriate steering behaviors for our agents - v.seek(mouse); - v.update(); - v.display(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_02_Arrive/Vehicle.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_02_Arrive/Vehicle.pde deleted file mode 100644 index d16f0fc94..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_02_Arrive/Vehicle.pde +++ /dev/null @@ -1,80 +0,0 @@ -// Seek_Arrive -// Daniel Shiffman - -// The "Vehicle" class - -class Vehicle { - - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - Vehicle(float x, float y) { - acceleration = new PVector(0,0); - velocity = new PVector(0,0); - location = new PVector(x,y); - r = 6; - maxspeed = 4; - maxforce = 0.1; - } - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelerationelertion to 0 each cycle - acceleration.mult(0); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - // A method that calculates a steering force towards a target - // STEER = DESIRED MINUS VELOCITY - void arrive(PVector target) { - PVector desired = PVector.sub(target,location); // A vector pointing from the location to the target - float d = desired.mag(); - // Normalize desired and scale with arbitrary damping within 100 pixels - desired.normalize(); - if (d < 100) { - float m = map(d,0,100,0,maxspeed); - desired.mult(m); - } else { - desired.mult(maxspeed); - } - - // Steering = Desired minus Velocity - PVector steer = PVector.sub(desired,velocity); - steer.limit(maxforce); // Limit to maximum steering force - applyForce(steer); - } - - void display() { - - // Draw a triangle rotated in the direction of velocity - float theta = velocity.heading2D() + PI/2; - fill(127); - stroke(0); - strokeWeight(1); - pushMatrix(); - translate(location.x,location.y); - rotate(theta); - beginShape(); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(CLOSE); - popMatrix(); - - - } -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_02_Arrive/_6_02_Arrive.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_02_Arrive/_6_02_Arrive.pde deleted file mode 100644 index 0d6037343..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_02_Arrive/_6_02_Arrive.pde +++ /dev/null @@ -1,35 +0,0 @@ -// Seek_Arrive -// Daniel Shiffman -// Nature of Code, Spring 2011 - -// Two "vehicles" follow the mouse position - -// Implements Craig Reynold's autonomous steering behaviors -// One vehicle "seeks" -// One vehicle "arrives" -// See: http://www.red3d.com/cwr/ - -Vehicle v; - -void setup() { - size(800, 200); - v = new Vehicle(width/2, height/2); - smooth(); -} - -void draw() { - background(255); - - PVector mouse = new PVector(mouseX, mouseY); - - // Draw an ellipse at the mouse location - fill(200); - stroke(0); - strokeWeight(2); - ellipse(mouse.x, mouse.y, 48, 48); - - // Call the appropriate steering behaviors for our agents - v.arrive(mouse); - v.update(); - v.display(); -} diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_02_Arrive_trail/Vehicle.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_02_Arrive_trail/Vehicle.pde deleted file mode 100644 index b6c0f4649..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_02_Arrive_trail/Vehicle.pde +++ /dev/null @@ -1,96 +0,0 @@ -// Seek_Arrive -// Daniel Shiffman - -// The "Vehicle" class - -class Vehicle { - - ArrayList history = new ArrayList(); - - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - Vehicle(float x, float y) { - acceleration = new PVector(0,0); - velocity = new PVector(0,0); - location = new PVector(x,y); - r = 6; - maxspeed = 4; - maxforce = 0.1; - } - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelerationelertion to 0 each cycle - acceleration.mult(0); - - history.add(location.get()); - if (history.size() > 100) { - history.remove(0); - } - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - // A method that calculates a steering force towards a target - // STEER = DESIRED MINUS VELOCITY - void arrive(PVector target) { - PVector desired = PVector.sub(target,location); // A vector pointing from the location to the target - float d = desired.mag(); - // Normalize desired and scale with arbitrary damping within 100 pixels - desired.normalize(); - if (d < 100) { - float m = map(d,0,100,0,maxspeed); - desired.mult(m); - } else { - desired.mult(maxspeed); - } - - // Steering = Desired minus Velocity - PVector steer = PVector.sub(desired,velocity); - steer.limit(maxforce); // Limit to maximum steering force - applyForce(steer); - } - - void display() { - - beginShape(); - stroke(0); - strokeWeight(1); - noFill(); - for(PVector v: history) { - vertex(v.x,v.y); - } - endShape(); - - // Draw a triangle rotated in the direction of velocity - float theta = velocity.heading2D() + PI/2; - fill(127); - stroke(0); - strokeWeight(1); - pushMatrix(); - translate(location.x,location.y); - rotate(theta); - beginShape(); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(CLOSE); - popMatrix(); - - - } -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_02_Arrive_trail/_6_02_Arrive_trail.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_02_Arrive_trail/_6_02_Arrive_trail.pde deleted file mode 100644 index c0efbc4f5..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_02_Arrive_trail/_6_02_Arrive_trail.pde +++ /dev/null @@ -1,38 +0,0 @@ -// Seek_Arrive -// Daniel Shiffman -// Nature of Code, Spring 2011 - -// Two "vehicles" follow the mouse position - -// Implements Craig Reynold's autonomous steering behaviors -// One vehicle "seeks" -// One vehicle "arrives" -// See: http://www.red3d.com/cwr/ - -Vehicle v; - -void setup() { - size(800, 200); - v = new Vehicle(width/2, height/2); - smooth(); -} - -void draw() { - if (mousePressed) { - background(255); - - PVector mouse = new PVector(mouseX, mouseY); - - // Draw an ellipse at the mouse location - fill(200); - stroke(0); - strokeWeight(2); - ellipse(mouse.x, mouse.y, 48, 48); - - // Call the appropriate steering behaviors for our agents - v.arrive(mouse); - v.update(); - v.display(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_03_StayWithinWalls/Vehicle.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_03_StayWithinWalls/Vehicle.pde deleted file mode 100644 index 7f557cdd2..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_03_StayWithinWalls/Vehicle.pde +++ /dev/null @@ -1,92 +0,0 @@ -// Wander -// Daniel Shiffman -// The Nature of Code - -// The "Vehicle" class - -class Vehicle { - - PVector location; - PVector velocity; - PVector acceleration; - float r; - - float maxspeed; - float maxforce; - - Vehicle(float x, float y) { - acceleration = new PVector(0, 0); - velocity = new PVector(3, -2); - velocity.mult(5); - location = new PVector(x, y); - r = 6; - maxspeed = 3; - maxforce = 0.15; - } - - void run() { - update(); - display(); - } - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - } - - void boundaries() { - - PVector desired = null; - - if (location.x < d) { - desired = new PVector(maxspeed, velocity.y); - } - else if (location.x > width -d) { - desired = new PVector(-maxspeed, velocity.y); - } - - if (location.y < d) { - desired = new PVector(velocity.x, maxspeed); - } - else if (location.y > height-d) { - desired = new PVector(velocity.x, -maxspeed); - } - - if (desired != null) { - desired.normalize(); - desired.mult(maxspeed); - PVector steer = PVector.sub(desired, velocity); - steer.limit(maxforce); - applyForce(steer); - } - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - - void display() { - // Draw a triangle rotated in the direction of velocity - float theta = velocity.heading2D() + radians(90); - fill(127); - stroke(0); - pushMatrix(); - translate(location.x, location.y); - rotate(theta); - beginShape(TRIANGLES); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(); - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_03_StayWithinWalls/_6_03_StayWithinWalls.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_03_StayWithinWalls/_6_03_StayWithinWalls.pde deleted file mode 100644 index 5f54281c5..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_03_StayWithinWalls/_6_03_StayWithinWalls.pde +++ /dev/null @@ -1,37 +0,0 @@ -// Stay Within Walls -// Daniel Shiffman -// The Nature of Code - -// "Made-up" Steering behavior to stay within walls - - -Vehicle v; -boolean debug = true; - -float d = 25; - - -void setup() { - size(800, 200); - v = new Vehicle(width/2, height/2); - smooth(); -} - -void draw() { - background(255); - - if (debug) { - stroke(175); - noFill(); - rectMode(CENTER); - rect(width/2, height/2, width-d*2, height-d*2); - } - - v.boundaries(); - v.run(); -} - -void mousePressed() { - debug = !debug; -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_03_StayWithinWalls_trail/Vehicle.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_03_StayWithinWalls_trail/Vehicle.pde deleted file mode 100644 index 0d94054a4..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_03_StayWithinWalls_trail/Vehicle.pde +++ /dev/null @@ -1,108 +0,0 @@ -// Wander -// Daniel Shiffman -// The Nature of Code - -// The "Vehicle" class - -class Vehicle { - ArrayList history = new ArrayList(); - - PVector location; - PVector velocity; - PVector acceleration; - float r; - - float maxspeed; - float maxforce; - - Vehicle(float x, float y) { - acceleration = new PVector(0, 0); - velocity = new PVector(3, -2); - velocity.mult(5); - location = new PVector(x, y); - r = 6; - maxspeed = 3; - maxforce = 0.15; - } - - void run() { - update(); - display(); - } - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - - history.add(location.get()); - if (history.size() > 500) { - history.remove(0); - } - } - - void boundaries() { - - PVector desired = null; - - if (location.x < d) { - desired = new PVector(maxspeed, velocity.y); - } - else if (location.x > width -d) { - desired = new PVector(-maxspeed, velocity.y); - } - - if (location.y < d) { - desired = new PVector(velocity.x, maxspeed); - } - else if (location.y > height-d) { - desired = new PVector(velocity.x, -maxspeed); - } - - if (desired != null) { - desired.normalize(); - desired.mult(maxspeed); - PVector steer = PVector.sub(desired, velocity); - steer.limit(maxforce); - applyForce(steer); - } - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - - void display() { - beginShape(); - stroke(0); - strokeWeight(1); - noFill(); - for(PVector v: history) { - vertex(v.x,v.y); - } - endShape(); - - - // Draw a triangle rotated in the direction of velocity - float theta = velocity.heading2D() + radians(90); - fill(127); - stroke(0); - pushMatrix(); - translate(location.x, location.y); - rotate(theta); - beginShape(TRIANGLES); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(); - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_03_StayWithinWalls_trail/_6_03_StayWithinWalls_trail.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_03_StayWithinWalls_trail/_6_03_StayWithinWalls_trail.pde deleted file mode 100644 index 5f54281c5..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_03_StayWithinWalls_trail/_6_03_StayWithinWalls_trail.pde +++ /dev/null @@ -1,37 +0,0 @@ -// Stay Within Walls -// Daniel Shiffman -// The Nature of Code - -// "Made-up" Steering behavior to stay within walls - - -Vehicle v; -boolean debug = true; - -float d = 25; - - -void setup() { - size(800, 200); - v = new Vehicle(width/2, height/2); - smooth(); -} - -void draw() { - background(255); - - if (debug) { - stroke(175); - noFill(); - rectMode(CENTER); - rect(width/2, height/2, width-d*2, height-d*2); - } - - v.boundaries(); - v.run(); -} - -void mousePressed() { - debug = !debug; -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flow_Figures/FlowField.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flow_Figures/FlowField.pde deleted file mode 100644 index b3c4c4a73..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flow_Figures/FlowField.pde +++ /dev/null @@ -1,92 +0,0 @@ -// Flow Field Following -// Daniel Shiffman -// The Nature of Code, Spring 2011 - -class FlowField { - - // A flow field is a two dimensional array of PVectors - PVector[][] field; - int cols, rows; // Columns and Rows - int resolution; // How large is each "cell" of the flow field - - FlowField(int r) { - resolution = r; - // Determine the number of columns and rows based on sketch's width and height - cols = width/resolution; - rows = height/resolution; - field = new PVector[cols][rows]; - init(); - } - - void init() { - // Reseed noise so we get a new flow field every time - noiseSeed((int)random(10000)); - float xoff = 0; - for (int i = 0; i < cols; i++) { - float yoff = 0; - for (int j = 0; j < rows; j++) { - //float theta = random(TWO_PI); - //float theta = map(noise(xoff,yoff),0,1,0,TWO_PI); - float x = i*resolution; - float y = j*resolution; - PVector v = new PVector(width/2-x,-y); - v.normalize(); - // Polar to cartesian coordinate transformation to get x and y components of the vector - field[i][j] = v;// new PVector(cos(theta),sin(theta)); - yoff += 0.1; - } - xoff += 0.1; - } - } - - // Draw every vector - void display() { - for (int i = 0; i < cols; i++) { - for (int j = 0; j < rows; j++) { - //drawVector(field[i][j],i*resolution,j*resolution,resolution-2); - pushMatrix(); - //translate(i*resolution+arrow.width/2,j*resolution+arrow.height/2); - translate(i*resolution,j*resolution); - rotate(field[i][j].heading2D()); - imageMode(CENTER); - //scale(0.2); - image(a,0,0); - //shape(arrow,-arrow.width/2,-arrow.height/2); - //ellipse(0,0,8,8); - popMatrix(); - } - } - - } - - // Renders a vector object 'v' as an arrow and a location 'x,y' - void drawVector(PVector v, float x, float y, float scayl) { - pushMatrix(); - float arrowsize = 4; - // Translate to location to render vector - translate(x,y); - stroke(0,100); - // Call vector heading function to get direction (note that pointing up is a heading of 0) and rotate - rotate(v.heading2D()); - // Calculate length of vector & scale it to be bigger or smaller if necessary - float len = v.mag()*scayl; - // Draw three lines to make an arrow (draw pointing up since we've rotate to the proper direction) - line(0,0,len,0); - line(len,0,len-arrowsize,+arrowsize/2); - line(len,0,len-arrowsize,-arrowsize/2); - popMatrix(); - } - - PVector lookup(PVector lookup) { - int column = int(constrain(lookup.x/resolution,0,cols-1)); - int row = int(constrain(lookup.y/resolution,0,rows-1)); - return field[column][row].get(); - } - - -} - - - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flow_Figures/Vehicle.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flow_Figures/Vehicle.pde deleted file mode 100644 index bd4149236..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flow_Figures/Vehicle.pde +++ /dev/null @@ -1,85 +0,0 @@ -// Flow Field Following -// Daniel Shiffman -// The Nature of Code, Spring 2011 - -class Vehicle { - - // The usual stuff - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - Vehicle(PVector l, float ms, float mf) { - location = l.get(); - r = 3.0; - maxspeed = ms; - maxforce = mf; - acceleration = new PVector(0,0); - velocity = new PVector(0,0); - } - - public void run() { - update(); - borders(); - display(); - } - - - // Implementing Reynolds' flow field following algorithm - // http://www.red3d.com/cwr/steer/FlowFollow.html - void follow(FlowField flow) { - // What is the vector at that spot in the flow field? - PVector desired = flow.lookup(location); - // Scale it up by maxspeed - desired.mult(maxspeed); - // Steering is desired minus velocity - PVector steer = PVector.sub(desired, velocity); - steer.limit(maxforce); // Limit to maximum steering force - applyForce(steer); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - } - - void display() { - // Draw a triangle rotated in the direction of velocity - float theta = velocity.heading2D() + radians(90); - fill(175); - stroke(0); - pushMatrix(); - translate(location.x,location.y); - rotate(theta); - beginShape(TRIANGLES); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(); - popMatrix(); - } - - // Wraparound - void borders() { - if (location.x < -r) location.x = width+r; - if (location.y < -r) location.y = height+r; - if (location.x > width+r) location.x = -r; - if (location.y > height+r) location.y = -r; - } -} - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flow_Figures/_6_04_Flow_Figures.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flow_Figures/_6_04_Flow_Figures.pde deleted file mode 100644 index d688f62f6..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flow_Figures/_6_04_Flow_Figures.pde +++ /dev/null @@ -1,34 +0,0 @@ -// Flow Field Following -// Daniel Shiffman -// The Nature of Code - -// Via Reynolds: http://www.red3d.com/cwr/steer/FlowFollow.html - -// Flowfield object -FlowField flowfield; -PShape arrow; -PImage a; - -void setup() { - size(1800, 60*9); - smooth(); - // Make a new flow field with "resolution" of 16 - flowfield = new FlowField(60); - arrow = loadShape("arrow.svg"); - a = loadImage("arrow60.png"); -} - -void draw() { - background(255); - // Display the flowfield in "debug" mode - translate(30,30); - flowfield.display(); - saveFrame("ch6_exc6.png"); - noLoop(); -} -// Make a new flowfield -void mousePressed() { - flowfield.init(); -} - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flow_Figures/data/arrow.svg b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flow_Figures/data/arrow.svg deleted file mode 100644 index 0f34115e7..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flow_Figures/data/arrow.svg +++ /dev/null @@ -1,5149 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/FlowField.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/FlowField.pde deleted file mode 100644 index 9ce11b4fe..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/FlowField.pde +++ /dev/null @@ -1,77 +0,0 @@ -// Flow Field Following -// Daniel Shiffman -// The Nature of Code, Spring 2011 - -class FlowField { - - // A flow field is a two dimensional array of PVectors - PVector[][] field; - int cols, rows; // Columns and Rows - int resolution; // How large is each "cell" of the flow field - - FlowField(int r) { - resolution = r; - // Determine the number of columns and rows based on sketch's width and height - cols = width/resolution; - rows = height/resolution; - field = new PVector[cols][rows]; - init(); - } - - void init() { - // Reseed noise so we get a new flow field every time - noiseSeed((int)random(10000)); - float xoff = 0; - for (int i = 0; i < cols; i++) { - float yoff = 0; - for (int j = 0; j < rows; j++) { - float theta = map(noise(xoff,yoff),0,1,0,TWO_PI); - // Polar to cartesian coordinate transformation to get x and y components of the vector - field[i][j] = new PVector(cos(theta),sin(theta)); - yoff += 0.1; - } - xoff += 0.1; - } - } - - // Draw every vector - void display() { - for (int i = 0; i < cols; i++) { - for (int j = 0; j < rows; j++) { - drawVector(field[i][j],i*resolution,j*resolution,resolution-2); - } - } - - } - - // Renders a vector object 'v' as an arrow and a location 'x,y' - void drawVector(PVector v, float x, float y, float scayl) { - pushMatrix(); - float arrowsize = 4; - // Translate to location to render vector - translate(x,y); - stroke(0,100); - // Call vector heading function to get direction (note that pointing up is a heading of 0) and rotate - rotate(v.heading2D()); - // Calculate length of vector & scale it to be bigger or smaller if necessary - float len = v.mag()*scayl; - // Draw three lines to make an arrow (draw pointing up since we've rotate to the proper direction) - line(0,0,len,0); - //line(len,0,len-arrowsize,+arrowsize/2); - //line(len,0,len-arrowsize,-arrowsize/2); - popMatrix(); - } - - PVector lookup(PVector lookup) { - int column = int(constrain(lookup.x/resolution,0,cols-1)); - int row = int(constrain(lookup.y/resolution,0,rows-1)); - return field[column][row].get(); - } - - -} - - - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/Vehicle.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/Vehicle.pde deleted file mode 100644 index bd4149236..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/Vehicle.pde +++ /dev/null @@ -1,85 +0,0 @@ -// Flow Field Following -// Daniel Shiffman -// The Nature of Code, Spring 2011 - -class Vehicle { - - // The usual stuff - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - Vehicle(PVector l, float ms, float mf) { - location = l.get(); - r = 3.0; - maxspeed = ms; - maxforce = mf; - acceleration = new PVector(0,0); - velocity = new PVector(0,0); - } - - public void run() { - update(); - borders(); - display(); - } - - - // Implementing Reynolds' flow field following algorithm - // http://www.red3d.com/cwr/steer/FlowFollow.html - void follow(FlowField flow) { - // What is the vector at that spot in the flow field? - PVector desired = flow.lookup(location); - // Scale it up by maxspeed - desired.mult(maxspeed); - // Steering is desired minus velocity - PVector steer = PVector.sub(desired, velocity); - steer.limit(maxforce); // Limit to maximum steering force - applyForce(steer); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - } - - void display() { - // Draw a triangle rotated in the direction of velocity - float theta = velocity.heading2D() + radians(90); - fill(175); - stroke(0); - pushMatrix(); - translate(location.x,location.y); - rotate(theta); - beginShape(TRIANGLES); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(); - popMatrix(); - } - - // Wraparound - void borders() { - if (location.x < -r) location.x = width+r; - if (location.y < -r) location.y = height+r; - if (location.x > width+r) location.x = -r; - if (location.y > height+r) location.y = -r; - } -} - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/_6_04_Flowfield.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/_6_04_Flowfield.pde deleted file mode 100644 index 805ea5962..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/_6_04_Flowfield.pde +++ /dev/null @@ -1,55 +0,0 @@ -// Flow Field Following -// Daniel Shiffman -// The Nature of Code - -// Via Reynolds: http://www.red3d.com/cwr/steer/FlowFollow.html - -// Using this variable to decide whether to draw all the stuff -boolean debug = true; - -// Flowfield object -FlowField flowfield; -// An ArrayList of vehicles -ArrayList vehicles; - -void setup() { - size(800, 200); - smooth(); - // Make a new flow field with "resolution" of 16 - flowfield = new FlowField(20); - vehicles = new ArrayList(); - // Make a whole bunch of vehicles with random maxspeed and maxforce values - for (int i = 0; i < 120; i++) { - vehicles.add(new Vehicle(new PVector(random(width), random(height)), random(2, 5), random(0.1, 0.5))); - } -} - -void draw() { - background(255); - // Display the flowfield in "debug" mode - if (debug) flowfield.display(); - // Tell all the vehicles to follow the flow field - for (Vehicle v : vehicles) { - v.follow(flowfield); - v.run(); - } - - // Instructions - fill(0); - text("Hit space bar to toggle debugging lines.\nClick the mouse to generate a new flow field.",10,height-20); -} - - -void keyPressed() { - if (key == ' ') { - debug = !debug; - } -} - -// Make a new flowfield -void mousePressed() { - flowfield.init(); -} - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/sketch.properties b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/sketch.properties deleted file mode 100644 index e69de29bb..000000000 diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/web-export/_6_04_Flowfield.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/web-export/_6_04_Flowfield.pde deleted file mode 100644 index 7fc20490e..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/web-export/_6_04_Flowfield.pde +++ /dev/null @@ -1,218 +0,0 @@ -// Flow Field Following -// Daniel Shiffman -// The Nature of Code - -// Via Reynolds: http://www.red3d.com/cwr/steer/FlowFollow.html - -// Using this variable to decide whether to draw all the stuff -boolean debug = true; - -// Flowfield object -FlowField flowfield; -// An ArrayList of vehicles -ArrayList vehicles; - -void setup() { - size(800, 200); - smooth(); - // Make a new flow field with "resolution" of 16 - flowfield = new FlowField(20); - vehicles = new ArrayList(); - // Make a whole bunch of vehicles with random maxspeed and maxforce values - for (int i = 0; i < 120; i++) { - vehicles.add(new Vehicle(new PVector(random(width), random(height)), random(2, 5), random(0.1, 0.5))); - } -} - -void draw() { - background(255); - // Display the flowfield in "debug" mode - if (debug) flowfield.display(); - // Tell all the vehicles to follow the flow field - for (Vehicle v : vehicles) { - v.follow(flowfield); - v.run(); - } - - // Instructions - fill(0); - text("Hit space bar to toggle debugging lines.\nClick the mouse to generate a new flow field.",10,height-20); -} - - -void keyPressed() { - if (key == ' ') { - debug = !debug; - } -} - -// Make a new flowfield -void mousePressed() { - flowfield.init(); -} - - - -// Flow Field Following -// Daniel Shiffman -// The Nature of Code, Spring 2011 - -class FlowField { - - // A flow field is a two dimensional array of PVectors - PVector[][] field; - int cols, rows; // Columns and Rows - int resolution; // How large is each "cell" of the flow field - - FlowField(int r) { - resolution = r; - // Determine the number of columns and rows based on sketch's width and height - cols = width/resolution; - rows = height/resolution; - field = new PVector[cols][rows]; - init(); - } - - void init() { - // Reseed noise so we get a new flow field every time - noiseSeed((int)random(10000)); - float xoff = 0; - for (int i = 0; i < cols; i++) { - float yoff = 0; - for (int j = 0; j < rows; j++) { - float theta = map(noise(xoff,yoff),0,1,0,TWO_PI); - // Polar to cartesian coordinate transformation to get x and y components of the vector - field[i][j] = new PVector(cos(theta),sin(theta)); - yoff += 0.1; - } - xoff += 0.1; - } - } - - // Draw every vector - void display() { - for (int i = 0; i < cols; i++) { - for (int j = 0; j < rows; j++) { - drawVector(field[i][j],i*resolution,j*resolution,resolution-2); - } - } - - } - - // Renders a vector object 'v' as an arrow and a location 'x,y' - void drawVector(PVector v, float x, float y, float scayl) { - pushMatrix(); - float arrowsize = 4; - // Translate to location to render vector - translate(x,y); - stroke(0,100); - // Call vector heading function to get direction (note that pointing up is a heading of 0) and rotate - rotate(v.heading2D()); - // Calculate length of vector & scale it to be bigger or smaller if necessary - float len = v.mag()*scayl; - // Draw three lines to make an arrow (draw pointing up since we've rotate to the proper direction) - line(0,0,len,0); - //line(len,0,len-arrowsize,+arrowsize/2); - //line(len,0,len-arrowsize,-arrowsize/2); - popMatrix(); - } - - PVector lookup(PVector lookup) { - int column = int(constrain(lookup.x/resolution,0,cols-1)); - int row = int(constrain(lookup.y/resolution,0,rows-1)); - return field[column][row].get(); - } - - -} - - - - - -// Flow Field Following -// Daniel Shiffman -// The Nature of Code, Spring 2011 - -class Vehicle { - - // The usual stuff - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - Vehicle(PVector l, float ms, float mf) { - location = l.get(); - r = 3.0; - maxspeed = ms; - maxforce = mf; - acceleration = new PVector(0,0); - velocity = new PVector(0,0); - } - - public void run() { - update(); - borders(); - display(); - } - - - // Implementing Reynolds' flow field following algorithm - // http://www.red3d.com/cwr/steer/FlowFollow.html - void follow(FlowField flow) { - // What is the vector at that spot in the flow field? - PVector desired = flow.lookup(location); - // Scale it up by maxspeed - desired.mult(maxspeed); - // Steering is desired minus velocity - PVector steer = PVector.sub(desired, velocity); - steer.limit(maxforce); // Limit to maximum steering force - applyForce(steer); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - } - - void display() { - // Draw a triangle rotated in the direction of velocity - float theta = velocity.heading2D() + radians(90); - fill(175); - stroke(0); - pushMatrix(); - translate(location.x,location.y); - rotate(theta); - beginShape(TRIANGLES); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(); - popMatrix(); - } - - // Wraparound - void borders() { - if (location.x < -r) location.x = width+r; - if (location.y < -r) location.y = height+r; - if (location.x > width+r) location.x = -r; - if (location.y > height+r) location.y = -r; - } -} - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/web-export/processing.js b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/web-export/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_04_Flowfield/web-export/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/Path.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/Path.pde deleted file mode 100644 index 611babb5b..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/Path.pde +++ /dev/null @@ -1,46 +0,0 @@ -// Path Following -// Daniel Shiffman -// The Nature of Code, Spring 2009 - -// Path Following -// Daniel Shiffman -// The Nature of Code, Spring 2009 - -class Path { - - // A Path is line between two points (PVector objects) - PVector start; - PVector end; - // A path has a radius, i.e how far is it ok for the boid to wander off - float radius; - - Path() { - // Arbitrary radius of 20 - radius = 20; - start = new PVector(0,height/3); - end = new PVector(width,2*height/3); - } - - // Draw the path - void display() { - - strokeWeight(radius*2); - stroke(0,100); - line(start.x,start.y,end.x,end.y); - - strokeWeight(1); - stroke(0); - line(start.x,start.y,end.x,end.y); - } -} - - - - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/Vehicle.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/Vehicle.pde deleted file mode 100644 index 109d7d658..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/Vehicle.pde +++ /dev/null @@ -1,161 +0,0 @@ -// Path Following -// Daniel Shiffman -// The Nature of Code, Spring 2009 - -// Vehicle class - -class Vehicle { - - // All the usual stuff - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - // Constructor initialize all values - Vehicle( PVector l, float ms, float mf) { - location = l.get(); - r = 4.0; - maxspeed = ms; - maxforce = mf; - acceleration = new PVector(0, 0); - velocity = new PVector(maxspeed, 0); - } - - // Main "run" function - void run() { - update(); - borders(); - render(); - } - - - // This function implements Craig Reynolds' path following algorithm - // http://www.red3d.com/cwr/steer/PathFollow.html - void follow(Path p) { - - // Predict location 25 (arbitrary choice) frames ahead - PVector predict = velocity.get(); - predict.normalize(); - predict.mult(25); - PVector predictLoc = PVector.add(location, predict); - - // Look at the line segment - PVector a = p.start; - PVector b = p.end; - - // Get the normal point to that line - PVector normalPoint = getNormalPoint(predictLoc, a, b); - - // Find target point a little further ahead of normal - PVector dir = PVector.sub(b, a); - dir.normalize(); - dir.mult(10); // This could be based on velocity instead of just an arbitrary 10 pixels - PVector target = PVector.add(normalPoint, dir); - - // How far away are we from the path? - float distance = PVector.dist(predictLoc, normalPoint); - // Only if the distance is greater than the path's radius do we bother to steer - if (distance > p.radius) { - seek(target); - } - - - // Draw the debugging stuff - if (debug) { - fill(0); - stroke(0); - line(location.x, location.y, predictLoc.x, predictLoc.y); - ellipse(predictLoc.x, predictLoc.y, 4, 4); - - // Draw normal location - fill(0); - stroke(0); - line(predictLoc.x, predictLoc.y, normalPoint.x, normalPoint.y); - ellipse(normalPoint.x, normalPoint.y, 4, 4); - stroke(0); - if (distance > p.radius) fill(255, 0, 0); - noStroke(); - ellipse(target.x+dir.x, target.y+dir.y, 8, 8); - } - } - - - // A function to get the normal point from a point (p) to a line segment (a-b) - // This function could be optimized to make fewer new Vector objects - PVector getNormalPoint(PVector p, PVector a, PVector b) { - // Vector from a to p - PVector ap = PVector.sub(p, a); - // Vector from a to b - PVector ab = PVector.sub(b, a); - ab.normalize(); // Normalize the line - // Project vector "diff" onto line by using the dot product - ab.mult(ap.dot(ab)); - PVector normalPoint = PVector.add(a, ab); - return normalPoint; - } - - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - - // A method that calculates and applies a steering force towards a target - // STEER = DESIRED MINUS VELOCITY - void seek(PVector target) { - PVector desired = PVector.sub(target, location); // A vector pointing from the location to the target - - // If the magnitude of desired equals 0, skip out of here - // (We could optimize this to check if x and y are 0 to avoid mag() square root - if (desired.mag() == 0) return; - - // Normalize desired and scale to maximum speed - desired.normalize(); - desired.mult(maxspeed); - // Steering = Desired minus Velocity - PVector steer = PVector.sub(desired, velocity); - steer.limit(maxforce); // Limit to maximum steering force - - applyForce(steer); - } - - void render() { - // Draw a triangle rotated in the direction of velocity - float theta = velocity.heading2D() + radians(90); - fill(175); - stroke(0); - pushMatrix(); - translate(location.x, location.y); - rotate(theta); - beginShape(PConstants.TRIANGLES); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(); - popMatrix(); - } - - // Wraparound - void borders() { - if (location.x < -r) location.x = width+r; - //if (location.y < -r) location.y = height+r; - if (location.x > width+r) location.x = -r; - //if (location.y > height+r) location.y = -r; - } -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/_6_05_PathFollowingSimple.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/_6_05_PathFollowingSimple.pde deleted file mode 100644 index 0fe9f7b0e..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/_6_05_PathFollowingSimple.pde +++ /dev/null @@ -1,52 +0,0 @@ -// Path Following -// Daniel Shiffman -// The Nature of Code - -// Path is a just a straight line in this example -// Via Reynolds: // http://www.red3d.com/cwr/steer/PathFollow.html - -// Using this variable to decide whether to draw all the stuff -boolean debug = true; - -// A path object (series of connected points) -Path path; - -// Two vehicles -Vehicle car1; -Vehicle car2; - -void setup() { - size(800, 200); - smooth(); - - path = new Path(); - - // Each vehicle has different maxspeed and maxforce for demo purposes - car1 = new Vehicle(new PVector(0, height/2), 3, 0.05); - car2 = new Vehicle(new PVector(0, height/2), 5, 0.1); -} - -void draw() { - background(255); - // Display the path - path.display(); - // The boids follow the path - car1.follow(path); - car2.follow(path); - // Call the generic run method (update, borders, display, etc.) - car1.run(); - car2.run(); - - // Instructions - fill(0); - text("Hit space bar to toggle debugging lines.", 10, height-30); -} - -public void keyPressed() { - if (key == ' ') { - debug = !debug; - } -} - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/sketch.properties b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/sketch.properties deleted file mode 100644 index 6d28cd598..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/sketch.properties +++ /dev/null @@ -1 +0,0 @@ -mode=JavaScript diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/web-export/_6_05_PathFollowingSimple.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/web-export/_6_05_PathFollowingSimple.pde deleted file mode 100644 index 5f5f3e2d4..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/web-export/_6_05_PathFollowingSimple.pde +++ /dev/null @@ -1,260 +0,0 @@ -// Path Following -// Daniel Shiffman -// The Nature of Code - -// Path is a just a straight line in this example -// Via Reynolds: // http://www.red3d.com/cwr/steer/PathFollow.html - -// Using this variable to decide whether to draw all the stuff -boolean debug = true; - -// A path object (series of connected points) -Path path; - -// Two vehicles -Vehicle car1; -Vehicle car2; - -void setup() { - size(800, 200); - smooth(); - - path = new Path(); - - // Each vehicle has different maxspeed and maxforce for demo purposes - car1 = new Vehicle(new PVector(0, height/2), 3, 0.05); - car2 = new Vehicle(new PVector(0, height/2), 5, 0.1); -} - -void draw() { - background(255); - // Display the path - path.display(); - // The boids follow the path - car1.follow(path); - car2.follow(path); - // Call the generic run method (update, borders, display, etc.) - car1.run(); - car2.run(); - - // Instructions - fill(0); - text("Hit space bar to toggle debugging lines.", 10, height-30); -} - -public void keyPressed() { - if (key == ' ') { - debug = !debug; - } -} - - - -// Path Following -// Daniel Shiffman -// The Nature of Code, Spring 2009 - -// Path Following -// Daniel Shiffman -// The Nature of Code, Spring 2009 - -class Path { - - // A Path is line between two points (PVector objects) - PVector start; - PVector end; - // A path has a radius, i.e how far is it ok for the boid to wander off - float radius; - - Path() { - // Arbitrary radius of 20 - radius = 20; - start = new PVector(0,height/3); - end = new PVector(width,2*height/3); - } - - // Draw the path - void display() { - - strokeWeight(radius*2); - stroke(0,100); - line(start.x,start.y,end.x,end.y); - - strokeWeight(1); - stroke(0); - line(start.x,start.y,end.x,end.y); - } -} - - - - - - - - - - - -// Path Following -// Daniel Shiffman -// The Nature of Code, Spring 2009 - -// Vehicle class - -class Vehicle { - - // All the usual stuff - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - // Constructor initialize all values - Vehicle( PVector l, float ms, float mf) { - location = l.get(); - r = 4.0; - maxspeed = ms; - maxforce = mf; - acceleration = new PVector(0, 0); - velocity = new PVector(maxspeed, 0); - } - - // Main "run" function - void run() { - update(); - borders(); - render(); - } - - - // This function implements Craig Reynolds' path following algorithm - // http://www.red3d.com/cwr/steer/PathFollow.html - void follow(Path p) { - - // Predict location 25 (arbitrary choice) frames ahead - PVector predict = velocity.get(); - predict.normalize(); - predict.mult(25); - PVector predictLoc = PVector.add(location, predict); - - // Look at the line segment - PVector a = p.start; - PVector b = p.end; - - // Get the normal point to that line - PVector normalPoint = getNormalPoint(predictLoc, a, b); - - // Find target point a little further ahead of normal - PVector dir = PVector.sub(b, a); - dir.normalize(); - dir.mult(10); // This could be based on velocity instead of just an arbitrary 10 pixels - PVector target = PVector.add(normalPoint, dir); - - // How far away are we from the path? - float distance = PVector.dist(predictLoc, normalPoint); - // Only if the distance is greater than the path's radius do we bother to steer - if (distance > p.radius) { - seek(target); - } - - - // Draw the debugging stuff - if (debug) { - fill(0); - stroke(0); - line(location.x, location.y, predictLoc.x, predictLoc.y); - ellipse(predictLoc.x, predictLoc.y, 4, 4); - - // Draw normal location - fill(0); - stroke(0); - line(predictLoc.x, predictLoc.y, normalPoint.x, normalPoint.y); - ellipse(normalPoint.x, normalPoint.y, 4, 4); - stroke(0); - if (distance > p.radius) fill(255, 0, 0); - noStroke(); - ellipse(target.x+dir.x, target.y+dir.y, 8, 8); - } - } - - - // A function to get the normal point from a point (p) to a line segment (a-b) - // This function could be optimized to make fewer new Vector objects - PVector getNormalPoint(PVector p, PVector a, PVector b) { - // Vector from a to p - PVector ap = PVector.sub(p, a); - // Vector from a to b - PVector ab = PVector.sub(b, a); - ab.normalize(); // Normalize the line - // Project vector "diff" onto line by using the dot product - ab.mult(ap.dot(ab)); - PVector normalPoint = PVector.add(a, ab); - return normalPoint; - } - - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - - // A method that calculates and applies a steering force towards a target - // STEER = DESIRED MINUS VELOCITY - void seek(PVector target) { - PVector desired = PVector.sub(target, location); // A vector pointing from the location to the target - - // If the magnitude of desired equals 0, skip out of here - // (We could optimize this to check if x and y are 0 to avoid mag() square root - if (desired.mag() == 0) return; - - // Normalize desired and scale to maximum speed - desired.normalize(); - desired.mult(maxspeed); - // Steering = Desired minus Velocity - PVector steer = PVector.sub(desired, velocity); - steer.limit(maxforce); // Limit to maximum steering force - - applyForce(steer); - } - - void render() { - // Draw a triangle rotated in the direction of velocity - float theta = velocity.heading2D() + radians(90); - fill(175); - stroke(0); - pushMatrix(); - translate(location.x, location.y); - rotate(theta); - beginShape(PConstants.TRIANGLES); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(); - popMatrix(); - } - - // Wraparound - void borders() { - if (location.x < -r) location.x = width+r; - //if (location.y < -r) location.y = height+r; - if (location.x > width+r) location.x = -r; - //if (location.y > height+r) location.y = -r; - } -} - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/web-export/processing.js b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/web-export/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_05_PathFollowingSimple/web-export/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_06_PathFollowing/Path.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_06_PathFollowing/Path.pde deleted file mode 100644 index d408cd460..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_06_PathFollowing/Path.pde +++ /dev/null @@ -1,48 +0,0 @@ -// Path Following -// Daniel Shiffman -// The Nature of Code - -class Path { - - // A Path is an arraylist of points (PVector objects) - ArrayList points; - // A path has a radius, i.e how far is it ok for the boid to wander off - float radius; - - Path() { - // Arbitrary radius of 20 - radius = 20; - points = new ArrayList(); - } - - // Add a point to the path - void addPoint(float x, float y) { - PVector point = new PVector(x, y); - points.add(point); - } - - // Draw the path - void display() { - // Draw thick line for radius - stroke(175); - strokeWeight(radius*2); - noFill(); - beginShape(); - for (PVector v : points) { - vertex(v.x, v.y); - } - endShape(); - // Draw thin line for center of path - stroke(0); - strokeWeight(1); - noFill(); - beginShape(); - for (PVector v : points) { - vertex(v.x, v.y); - } - endShape(); - } -} - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_06_PathFollowing/Vehicle.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_06_PathFollowing/Vehicle.pde deleted file mode 100644 index 543e45c8e..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_06_PathFollowing/Vehicle.pde +++ /dev/null @@ -1,190 +0,0 @@ -// Path Following -// Daniel Shiffman -// The Nature of Code - -// Vehicle class - -class Vehicle { - - // All the usual stuff - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - // Constructor initialize all values - Vehicle( PVector l, float ms, float mf) { - location = l.get(); - r = 4.0; - maxspeed = ms; - maxforce = mf; - acceleration = new PVector(0, 0); - velocity = new PVector(maxspeed, 0); - } - - // Main "run" function - public void run() { - update(); - borders(); - render(); - } - - - // This function implements Craig Reynolds' path following algorithm - // http://www.red3d.com/cwr/steer/PathFollow.html - void follow(Path p) { - - // Predict location 25 (arbitrary choice) frames ahead - PVector predict = velocity.get(); - predict.normalize(); - predict.mult(25); - PVector predictLoc = PVector.add(location, predict); - - // Now we must find the normal to the path from the predicted location - // We look at the normal for each line segment and pick out the closest one - - PVector normal = null; - PVector target = null; - float worldRecord = 1000000; // Start with a very high record distance that can easily be beaten - - // Loop through all points of the path - for (int i = 0; i < p.points.size()-1; i++) { - - // Look at a line segment - PVector a = p.points.get(i); - PVector b = p.points.get(i+1); - - // Get the normal point to that line - PVector normalPoint = getNormalPoint(predictLoc, a, b); - // This only works because we know our path goes from left to right - // We could have a more sophisticated test to tell if the point is in the line segment or not - if (normalPoint.x < a.x || normalPoint.x > b.x) { - // This is something of a hacky solution, but if it's not within the line segment - // consider the normal to just be the end of the line segment (point b) - normalPoint = b.get(); - } - - // How far away are we from the path? - float distance = PVector.dist(predictLoc, normalPoint); - // Did we beat the record and find the closest line segment? - if (distance < worldRecord) { - worldRecord = distance; - // If so the target we want to steer towards is the normal - normal = normalPoint; - - // Look at the direction of the line segment so we can seek a little bit ahead of the normal - PVector dir = PVector.sub(b, a); - dir.normalize(); - // This is an oversimplification - // Should be based on distance to path & velocity - dir.mult(10); - target = normalPoint.get(); - target.add(dir); - } - } - - // Only if the distance is greater than the path's radius do we bother to steer - if (worldRecord > p.radius) { - seek(target); - } - - - // Draw the debugging stuff - if (debug) { - // Draw predicted future location - stroke(0); - fill(0); - line(location.x, location.y, predictLoc.x, predictLoc.y); - ellipse(predictLoc.x, predictLoc.y, 4, 4); - - // Draw normal location - stroke(0); - fill(0); - ellipse(normal.x, normal.y, 4, 4); - // Draw actual target (red if steering towards it) - line(predictLoc.x, predictLoc.y, normal.x, normal.y); - if (worldRecord > p.radius) fill(255, 0, 0); - noStroke(); - ellipse(target.x, target.y, 8, 8); - } - } - - - // A function to get the normal point from a point (p) to a line segment (a-b) - // This function could be optimized to make fewer new Vector objects - PVector getNormalPoint(PVector p, PVector a, PVector b) { - // Vector from a to p - PVector ap = PVector.sub(p, a); - // Vector from a to b - PVector ab = PVector.sub(b, a); - ab.normalize(); // Normalize the line - // Project vector "diff" onto line by using the dot product - ab.mult(ap.dot(ab)); - PVector normalPoint = PVector.add(a, ab); - return normalPoint; - } - - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - - // A method that calculates and applies a steering force towards a target - // STEER = DESIRED MINUS VELOCITY - void seek(PVector target) { - PVector desired = PVector.sub(target, location); // A vector pointing from the location to the target - - // If the magnitude of desired equals 0, skip out of here - // (We could optimize this to check if x and y are 0 to avoid mag() square root - if (desired.mag() == 0) return; - - // Normalize desired and scale to maximum speed - desired.normalize(); - desired.mult(maxspeed); - // Steering = Desired minus Velocity - PVector steer = PVector.sub(desired, velocity); - steer.limit(maxforce); // Limit to maximum steering force - - applyForce(steer); - } - - void render() { - // Draw a triangle rotated in the direction of velocity - float theta = velocity.heading2D() + radians(90); - fill(175); - stroke(0); - pushMatrix(); - translate(location.x, location.y); - rotate(theta); - beginShape(PConstants.TRIANGLES); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(); - popMatrix(); - } - - // Wraparound - void borders() { - if (location.x < -r) location.x = width+r; - //if (location.y < -r) location.y = height+r; - if (location.x > width+r) location.x = -r; - //if (location.y > height+r) location.y = -r; - } -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_06_PathFollowing/_6_06_PathFollowing.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_06_PathFollowing/_6_06_PathFollowing.pde deleted file mode 100644 index 09b097ddb..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_06_PathFollowing/_6_06_PathFollowing.pde +++ /dev/null @@ -1,65 +0,0 @@ -// Path Following -// Daniel Shiffman -// The Nature of Code - -// Via Reynolds: // http://www.red3d.com/cwr/steer/PathFollow.html - -// Using this variable to decide whether to draw all the stuff -boolean debug = true; - -// A path object (series of connected points) -Path path; - -// Two vehicles -Vehicle car1; -Vehicle car2; - -void setup() { - size(800, 200); - smooth(); - - // Call a function to generate new Path object - newPath(); - - // Each vehicle has different maxspeed and maxforce for demo purposes - car1 = new Vehicle(new PVector(0, height/2), 3, 0.1); - car2 = new Vehicle(new PVector(0, height/2), 5, 0.2); -} - -void draw() { - background(255); - // Display the path - path.display(); - // The boids follow the path - car1.follow(path); - car2.follow(path); - // Call the generic run method (update, borders, display, etc.) - car1.run(); - car2.run(); - - // Instructions - fill(0); - text("Hit space bar to toggle debugging lines.\nClick the mouse to generate a new path.", 10, height-30); -} - -void newPath() { - // A path is a series of connected points - // A more sophisticated path might be a curve - path = new Path(); - path.addPoint(0, height/2); - path.addPoint(random(0, width/2), random(0, height)); - path.addPoint(random(width/2, width), random(0, height)); - path.addPoint(width, height/2); -} - -public void keyPressed() { - if (key == ' ') { - debug = !debug; - } -} - -public void mousePressed() { - newPath(); -} - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_07_Separation/Vehicle.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_07_Separation/Vehicle.pde deleted file mode 100644 index e115f2394..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_07_Separation/Vehicle.pde +++ /dev/null @@ -1,99 +0,0 @@ -// Separation -// Daniel Shiffman -// The Nature of Code, 2011 - -// Vehicle class - -class Vehicle { - - // All the usual stuff - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - // Constructor initialize all values - Vehicle(float x, float y) { - location = new PVector(x, y); - r = 12; - maxspeed = 3; - maxforce = 0.2; - acceleration = new PVector(0, 0); - velocity = new PVector(0, 0); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - // Separation - // Method checks for nearby vehicles and steers away - void separate (ArrayList vehicles) { - float desiredseparation = r*2; - PVector sum = new PVector(); - int count = 0; - // For every boid in the system, check if it's too close - for (Vehicle other : vehicles) { - float d = PVector.dist(location, other.location); - // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) - if ((d > 0) && (d < desiredseparation)) { - // Calculate vector pointing away from neighbor - PVector diff = PVector.sub(location, other.location); - diff.normalize(); - diff.div(d); // Weight by distance - sum.add(diff); - count++; // Keep track of how many - } - } - // Average -- divide by how many - if (count > 0) { - sum.div(count); - // Our desired vector is the average scaled to maximum speed - sum.normalize(); - sum.mult(maxspeed); - // Implement Reynolds: Steering = Desired - Velocity - PVector steer = PVector.sub(sum, velocity); - steer.limit(maxforce); - applyForce(steer); - } - } - - - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - } - - void display() { - fill(175); - stroke(0); - pushMatrix(); - translate(location.x, location.y); - ellipse(0, 0, r, r); - popMatrix(); - } - - // Wraparound - void borders() { - if (location.x < -r) location.x = width+r; - if (location.y < -r) location.y = height+r; - if (location.x > width+r) location.x = -r; - if (location.y > height+r) location.y = -r; - } -} - - - - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_07_Separation/_6_07_Separation.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_07_Separation/_6_07_Separation.pde deleted file mode 100644 index 92d96bb0e..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_07_Separation/_6_07_Separation.pde +++ /dev/null @@ -1,45 +0,0 @@ -// Separation -// Daniel Shiffman -// The Nature of Code, 2011 - -// Via Reynolds: http://www.red3d.com/cwr/steer/ - -// A list of vehicles -ArrayList vehicles; - -void setup() { - size(800,200); - smooth(); - - // We are now making random vehicles and storing them in an ArrayList - vehicles = new ArrayList(); - for (int i = 0; i < 100; i++) { - vehicles.add(new Vehicle(random(width),random(height))); - } -} - -void draw() { - background(255); - - for (Vehicle v : vehicles) { - // Path following and separation are worked on in this function - v.separate(vehicles); - // Call the generic run method (update, borders, display, etc.) - v.update(); - v.borders(); - v.display(); - } - - // Instructions - fill(0); - text("Drag the mouse to generate new vehicles.",10,height-16); -} - - -void mouseDragged() { - vehicles.add(new Vehicle(mouseX,mouseY)); -} - - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/Vehicle.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/Vehicle.pde deleted file mode 100644 index a78653ffe..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/Vehicle.pde +++ /dev/null @@ -1,115 +0,0 @@ -// Separation -// Daniel Shiffman -// The Nature of Code, 2011 - -// Vehicle class - -class Vehicle { - - // All the usual stuff - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - // Constructor initialize all values - Vehicle(float x, float y) { - location = new PVector(x, y); - r = 12; - maxspeed = 3; - maxforce = 0.2; - acceleration = new PVector(0, 0); - velocity = new PVector(0, 0); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - void applyBehaviors(ArrayList vehicles) { - PVector separateForce = separate(vehicles); - PVector seekForce = seek(new PVector(mouseX,mouseY)); - separateForce.mult(2); - seekForce.mult(1); - applyForce(separateForce); - applyForce(seekForce); - } - - // A method that calculates a steering force towards a target - // STEER = DESIRED MINUS VELOCITY - PVector seek(PVector target) { - PVector desired = PVector.sub(target,location); // A vector pointing from the location to the target - - // Normalize desired and scale to maximum speed - desired.normalize(); - desired.mult(maxspeed); - // Steering = Desired minus velocity - PVector steer = PVector.sub(desired,velocity); - steer.limit(maxforce); // Limit to maximum steering force - - return steer; - } - - // Separation - // Method checks for nearby vehicles and steers away - PVector separate (ArrayList vehicles) { - float desiredseparation = r*2; - PVector sum = new PVector(); - int count = 0; - // For every boid in the system, check if it's too close - for (Vehicle other : vehicles) { - float d = PVector.dist(location, other.location); - // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) - if ((d > 0) && (d < desiredseparation)) { - // Calculate vector pointing away from neighbor - PVector diff = PVector.sub(location, other.location); - diff.normalize(); - diff.div(d); // Weight by distance - sum.add(diff); - count++; // Keep track of how many - } - } - // Average -- divide by how many - if (count > 0) { - sum.div(count); - // Our desired vector is the average scaled to maximum speed - sum.normalize(); - sum.mult(maxspeed); - // Implement Reynolds: Steering = Desired - Velocity - sum.sub(velocity); - sum.limit(maxforce); - } - return sum; - } - - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - } - - void display() { - fill(175); - stroke(0); - pushMatrix(); - translate(location.x, location.y); - ellipse(0, 0, r, r); - popMatrix(); - } - -} - - - - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/_6_08_SeparationAndSeek.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/_6_08_SeparationAndSeek.pde deleted file mode 100644 index c1614c97f..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/_6_08_SeparationAndSeek.pde +++ /dev/null @@ -1,43 +0,0 @@ -// Separation -// Daniel Shiffman -// The Nature of Code, 2011 - -// Via Reynolds: http://www.red3d.com/cwr/steer/ - -// A list of vehicles -ArrayList vehicles; - -void setup() { - size(800,200); - smooth(); - - // We are now making random vehicles and storing them in an ArrayList - vehicles = new ArrayList(); - for (int i = 0; i < 100; i++) { - vehicles.add(new Vehicle(random(width),random(height))); - } -} - -void draw() { - background(255); - - for (Vehicle v : vehicles) { - // Path following and separation are worked on in this function - v.applyBehaviors(vehicles); - // Call the generic run method (update, borders, display, etc.) - v.update(); - v.display(); - } - - // Instructions - fill(0); - text("Drag the mouse to generate new vehicles.",10,height-16); -} - - -void mouseDragged() { - vehicles.add(new Vehicle(mouseX,mouseY)); -} - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/sketch.properties b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/sketch.properties deleted file mode 100644 index 6d28cd598..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/sketch.properties +++ /dev/null @@ -1 +0,0 @@ -mode=JavaScript diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/web-export/_6_08_SeparationAndSeek.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/web-export/_6_08_SeparationAndSeek.pde deleted file mode 100644 index 7c6f3e3a5..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/web-export/_6_08_SeparationAndSeek.pde +++ /dev/null @@ -1,159 +0,0 @@ -// Separation -// Daniel Shiffman -// The Nature of Code, 2011 - -// Via Reynolds: http://www.red3d.com/cwr/steer/ - -// A list of vehicles -ArrayList vehicles; - -void setup() { - size(800,200); - smooth(); - - // We are now making random vehicles and storing them in an ArrayList - vehicles = new ArrayList(); - for (int i = 0; i < 100; i++) { - vehicles.add(new Vehicle(random(width),random(height))); - } -} - -void draw() { - background(255); - - for (Vehicle v : vehicles) { - // Path following and separation are worked on in this function - v.applyBehaviors(vehicles); - // Call the generic run method (update, borders, display, etc.) - v.update(); - v.display(); - } - - // Instructions - fill(0); - text("Drag the mouse to generate new vehicles.",10,height-16); -} - - -void mouseDragged() { - vehicles.add(new Vehicle(mouseX,mouseY)); -} - - - -// Separation -// Daniel Shiffman -// The Nature of Code, 2011 - -// Vehicle class - -class Vehicle { - - // All the usual stuff - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - // Constructor initialize all values - Vehicle(float x, float y) { - location = new PVector(x, y); - r = 12; - maxspeed = 3; - maxforce = 0.2; - acceleration = new PVector(0, 0); - velocity = new PVector(0, 0); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - void applyBehaviors(ArrayList vehicles) { - PVector separateForce = separate(vehicles); - PVector seekForce = seek(new PVector(mouseX,mouseY)); - separateForce.mult(2); - seekForce.mult(1); - applyForce(separateForce); - applyForce(seekForce); - } - - // A method that calculates a steering force towards a target - // STEER = DESIRED MINUS VELOCITY - PVector seek(PVector target) { - PVector desired = PVector.sub(target,location); // A vector pointing from the location to the target - - // Normalize desired and scale to maximum speed - desired.normalize(); - desired.mult(maxspeed); - // Steering = Desired minus velocity - PVector steer = PVector.sub(desired,velocity); - steer.limit(maxforce); // Limit to maximum steering force - - return steer; - } - - // Separation - // Method checks for nearby vehicles and steers away - PVector separate (ArrayList vehicles) { - float desiredseparation = r*2; - PVector sum = new PVector(); - int count = 0; - // For every boid in the system, check if it's too close - for (Vehicle other : vehicles) { - float d = PVector.dist(location, other.location); - // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) - if ((d > 0) && (d < desiredseparation)) { - // Calculate vector pointing away from neighbor - PVector diff = PVector.sub(location, other.location); - diff.normalize(); - diff.div(d); // Weight by distance - sum.add(diff); - count++; // Keep track of how many - } - } - // Average -- divide by how many - if (count > 0) { - sum.div(count); - // Our desired vector is the average scaled to maximum speed - sum.normalize(); - sum.mult(maxspeed); - // Implement Reynolds: Steering = Desired - Velocity - sum.sub(velocity); - sum.limit(maxforce); - } - return sum; - } - - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - } - - void display() { - fill(175); - stroke(0); - pushMatrix(); - translate(location.x, location.y); - ellipse(0, 0, r, r); - popMatrix(); - } - -} - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/web-export/processing.js b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/web-export/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_08_SeparationAndSeek/web-export/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_09_Flocking/Boid.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_09_Flocking/Boid.pde deleted file mode 100644 index 282e12f29..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_09_Flocking/Boid.pde +++ /dev/null @@ -1,182 +0,0 @@ -// Flocking -// Daniel Shiffman -// The Nature of Code, Spring 2009 - -// Boid class -// Methods for Separation, Cohesion, Alignment added - -class Boid { - - PVector location; - PVector velocity; - PVector acceleration; - float r; - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - Boid(float x, float y) { - acceleration = new PVector(0,0); - velocity = new PVector(random(-1,1),random(-1,1)); - location = new PVector(x,y); - r = 3.0; - maxspeed = 3; - maxforce = 0.05; - } - - void run(ArrayList boids) { - flock(boids); - update(); - borders(); - render(); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - // We accumulate a new acceleration each time based on three rules - void flock(ArrayList boids) { - PVector sep = separate(boids); // Separation - PVector ali = align(boids); // Alignment - PVector coh = cohesion(boids); // Cohesion - // Arbitrarily weight these forces - sep.mult(1.5); - ali.mult(1.0); - coh.mult(1.0); - // Add the force vectors to acceleration - applyForce(sep); - applyForce(ali); - applyForce(coh); - } - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - } - - // A method that calculates and applies a steering force towards a target - // STEER = DESIRED MINUS VELOCITY - PVector seek(PVector target) { - PVector desired = PVector.sub(target,location); // A vector pointing from the location to the target - // Normalize desired and scale to maximum speed - desired.normalize(); - desired.mult(maxspeed); - // Steering = Desired minus Velocity - PVector steer = PVector.sub(desired,velocity); - steer.limit(maxforce); // Limit to maximum steering force - return steer; - } - - void render() { - // Draw a triangle rotated in the direction of velocity - float theta = velocity.heading2D() + radians(90); - fill(175); - stroke(0); - pushMatrix(); - translate(location.x,location.y); - rotate(theta); - beginShape(TRIANGLES); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(); - popMatrix(); - } - - // Wraparound - void borders() { - if (location.x < -r) location.x = width+r; - if (location.y < -r) location.y = height+r; - if (location.x > width+r) location.x = -r; - if (location.y > height+r) location.y = -r; - } - - // Separation - // Method checks for nearby boids and steers away - PVector separate (ArrayList boids) { - float desiredseparation = 25.0f; - PVector steer = new PVector(0,0,0); - int count = 0; - // For every boid in the system, check if it's too close - for (Boid other : boids) { - float d = PVector.dist(location,other.location); - // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) - if ((d > 0) && (d < desiredseparation)) { - // Calculate vector pointing away from neighbor - PVector diff = PVector.sub(location,other.location); - diff.normalize(); - diff.div(d); // Weight by distance - steer.add(diff); - count++; // Keep track of how many - } - } - // Average -- divide by how many - if (count > 0) { - steer.div((float)count); - } - - // As long as the vector is greater than 0 - if (steer.mag() > 0) { - // Implement Reynolds: Steering = Desired - Velocity - steer.normalize(); - steer.mult(maxspeed); - steer.sub(velocity); - steer.limit(maxforce); - } - return steer; - } - - // Alignment - // For every nearby boid in the system, calculate the average velocity - PVector align (ArrayList boids) { - float neighbordist = 50; - PVector sum = new PVector(0,0); - int count = 0; - for (Boid other : boids) { - float d = PVector.dist(location,other.location); - if ((d > 0) && (d < neighbordist)) { - sum.add(other.velocity); - count++; - } - } - if (count > 0) { - sum.div((float)count); - sum.normalize(); - sum.mult(maxspeed); - PVector steer = PVector.sub(sum,velocity); - steer.limit(maxforce); - return steer; - } else { - return new PVector(0,0); - } - } - - // Cohesion - // For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location - PVector cohesion (ArrayList boids) { - float neighbordist = 50; - PVector sum = new PVector(0,0); // Start with empty vector to accumulate all locations - int count = 0; - for (Boid other : boids) { - float d = PVector.dist(location,other.location); - if ((d > 0) && (d < neighbordist)) { - sum.add(other.location); // Add location - count++; - } - } - if (count > 0) { - sum.div(count); - return seek(sum); // Steer towards the location - } else { - return new PVector(0,0); - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_09_Flocking/Flock.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_09_Flocking/Flock.pde deleted file mode 100644 index eb7458e5a..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_09_Flocking/Flock.pde +++ /dev/null @@ -1,25 +0,0 @@ -// Flocking -// Daniel Shiffman -// The Nature of Code, Spring 2011 - -// Flock class -// Does very little, simply manages the ArrayList of all the boids - -class Flock { - ArrayList boids; // An ArrayList for all the boids - - Flock() { - boids = new ArrayList(); // Initialize the ArrayList - } - - void run() { - for (Boid b : boids) { - b.run(boids); // Passing the entire list of boids to each boid individually - } - } - - void addBoid(Boid b) { - boids.add(b); - } - -} diff --git a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_09_Flocking/_6_09_Flocking.pde b/java/examples/Books/Nature of Code/chp6_agents/NOC_6_09_Flocking/_6_09_Flocking.pde deleted file mode 100644 index c1c12b7f3..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/NOC_6_09_Flocking/_6_09_Flocking.pde +++ /dev/null @@ -1,38 +0,0 @@ -// Flocking -// Daniel Shiffman -// The Nature of Code, Spring 2009 - -// Demonstration of Craig Reynolds' "Flocking" behavior -// See: http://www.red3d.com/cwr/ -// Rules: Cohesion, Separation, Alignment - -// Click mouse to add boids into the system - -Flock flock; - -void setup() { - size(800,200); - flock = new Flock(); - // Add an initial set of boids into the system - for (int i = 0; i < 200; i++) { - Boid b = new Boid(width/2,height/2); - flock.addBoid(b); - } - smooth(); -} - -void draw() { - background(255); - flock.run(); - - // Instructions - fill(0); - //text("Drag the mouse to generate new boids.",10,height-16); -} - -// Add a new boid into the System -void mouseDragged() { - flock.addBoid(new Boid(mouseX,mouseY)); -} - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/StayWithinCircle/StayWithinCircle.pde b/java/examples/Books/Nature of Code/chp6_agents/StayWithinCircle/StayWithinCircle.pde deleted file mode 100644 index 0b42a37be..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/StayWithinCircle/StayWithinCircle.pde +++ /dev/null @@ -1,43 +0,0 @@ -// Stay Within Walls -// Daniel Shiffman -// The Nature of Code - -// "Made-up" Steering behavior to stay within walls - - -Vehicle v; -boolean debug = true; - - -PVector circleLocation; -float circleRadius; - - - -void setup() { - size(640, 360); - v = new Vehicle(width/2, height/4); - - circleLocation = new PVector(width/2,height/2); - circleRadius = height/2-25; - - smooth(); -} - -void draw() { - background(255); - - if (debug) { - stroke(175); - noFill(); - ellipse(circleLocation.x,circleLocation.y, circleRadius*2,circleRadius*2); - } - - v.boundaries(); - v.run(); -} - -void mousePressed() { - debug = !debug; -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/StayWithinCircle/Vehicle.pde b/java/examples/Books/Nature of Code/chp6_agents/StayWithinCircle/Vehicle.pde deleted file mode 100644 index fcd3e7a56..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/StayWithinCircle/Vehicle.pde +++ /dev/null @@ -1,95 +0,0 @@ -// Wander -// Daniel Shiffman -// The Nature of Code - -// The "Vehicle" class (for wandering) - -class Vehicle { - - PVector location; - PVector velocity; - PVector acceleration; - float r; - - float maxspeed; - float maxforce; - - Vehicle(float x, float y) { - acceleration = new PVector(0, 0); - velocity = new PVector(1,0); - velocity.mult(5); - location = new PVector(x, y); - r = 3; - maxspeed = 3; - maxforce = 0.15; - } - - void run() { - update(); - display(); - } - - // Method to update location - void update() { - // Update velocity - velocity.add(acceleration); - // Limit speed - velocity.limit(maxspeed); - location.add(velocity); - // Reset accelertion to 0 each cycle - acceleration.mult(0); - } - - void boundaries() { - - PVector desired = null; - - // Predict location 25 (arbitrary choice) frames ahead - PVector predict = velocity.get(); - predict.mult(25); - PVector futureLocation = PVector.add(location, predict); - float distance = PVector.dist(futureLocation,circleLocation); - - if (distance > circleRadius) { - PVector toCenter = PVector.sub(circleLocation,location); - toCenter.normalize(); - toCenter.mult(velocity.mag()); - desired = PVector.add(velocity,toCenter); - desired.normalize(); - desired.mult(maxspeed); - } - - if (desired != null) { - PVector steer = PVector.sub(desired, velocity); - steer.limit(maxforce); - applyForce(steer); - } - - fill(255,0,0); - ellipse(futureLocation.x,futureLocation.y,4,4); - - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acceleration.add(force); - } - - - void display() { - // Draw a triangle rotated in the direction of velocity - float theta = velocity.heading2D() + radians(90); - fill(175); - stroke(0); - pushMatrix(); - translate(location.x, location.y); - rotate(theta); - beginShape(TRIANGLES); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(); - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/binlatticespatialsubdivision/intersection/intersection/Thing.pde b/java/examples/Books/Nature of Code/chp6_agents/binlatticespatialsubdivision/intersection/intersection/Thing.pde deleted file mode 100644 index 5618479db..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/binlatticespatialsubdivision/intersection/intersection/Thing.pde +++ /dev/null @@ -1,32 +0,0 @@ -// Daniel Shiffman -// -// April 6, 2006 - -// Simple class describing an ellipse living on our screen - -class Thing { - - float x,y; - boolean highlight; - float r; - - Thing (float x_, float y_) { - x = x_; - y = y_; - highlight = false; - r = random(8) + 1; - } - - void move() { - x += random(-1,1); - y += random(-1,1); - } - - void render() { - noStroke(); - if (highlight) fill(255); - else fill(100); - ellipse(x,y,r,r); - } - -} diff --git a/java/examples/Books/Nature of Code/chp6_agents/binlatticespatialsubdivision/intersection/intersection/intersection.pde b/java/examples/Books/Nature of Code/chp6_agents/binlatticespatialsubdivision/intersection/intersection/intersection.pde deleted file mode 100644 index 542c90d3b..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/binlatticespatialsubdivision/intersection/intersection/intersection.pde +++ /dev/null @@ -1,106 +0,0 @@ -// Daniel Shiffman -// - -// Bin-Lattice Spatial Subdivision -// http://www.red3d.com/cwr/papers/2000/pip.pdf - -// Example demonstrating optimized intersection test for large # of objects -// Each object registers its location in a virtual grid -// Only the objects in neighboring cells on the grid are tested against each other - -int totalThings = 2000; - -ArrayList a; // ArrayList for all "things" -ArrayList[][] grid; // Grid of ArrayLists for intersection test -int scl = 4; // Size of each grid cell -int cols, rows; // Total coluns and rows - -void setup() { - size(640,360); - smooth(); - - a = new ArrayList(); // Create the list - cols = width/scl; // Calculate cols & rows - rows = height/scl; - - // Initialize grid as 2D array of empty ArrayLists - grid = new ArrayList[cols][rows]; - for (int i = 0; i < cols; i++) { - for (int j = 0; j < rows; j++) { - grid[i][j] = new ArrayList(); - } - } - - // Put 2000 Things in the system - for (int i = 0; i < totalThings; i++) { - a.add(new Thing(random(width),random(height))); - } - -} - -void draw() { - background(0); - - // Every time through draw clear all the lists - for (int i = 0; i < cols; i++) { - for (int j = 0; j < rows; j++) { - grid[i][j].clear(); - } - } - - // Register every Thing object in the grid according to it's location - for (Thing t : a) { - t.highlight = false; - int x = int(t.x) / scl; - int y = int (t.y) /scl; - // It goes in 9 cells, i.e. every Thing is tested against other Things in its cell - // as well as its 8 neighbors - for (int n = -1; n <= 1; n++) { - for (int m = -1; m <= 1; m++) { - if (x+n >= 0 && x+n < cols && y+m >= 0 && y+m< rows) grid[x+n][y+m].add(t); - } - } - } - - // Run through the Grid - stroke(255); - for (int i = 0; i < cols; i++) { - //line(i*scl,0,i*scl,height); - for (int j = 0; j < rows; j++) { - //line(0,j*scl,width,j*scl); - - // For every list in the grid - ArrayList temp = grid[i][j]; - // Check every Thing - for (Thing t : temp) { - // Against every other Thing - for (Thing other : temp) { - // As long as its not the same one - if (other != t) { - // Check to see if they are touching - // (We could do many other things here besides just intersection tests, such - // as apply forces, etc.) - float d = dist(t.x,t.y,other.x,other.y); - if (d < t.r/2 + other.r/2) { - t.highlight = true; - } - } - } - } - } - } - - // Display and move all Things - for (Thing t : a) { - t.render(); - t.move(); - } - - fill(0); - rect(0,height-20,width,20); - fill(255); - text("Framerate: " + int(frameRate),10,height-6); - - - -} diff --git a/java/examples/Books/Nature of Code/chp6_agents/binlatticespatialsubdivision/intersection/intersection_slow/Thing.pde b/java/examples/Books/Nature of Code/chp6_agents/binlatticespatialsubdivision/intersection/intersection_slow/Thing.pde deleted file mode 100644 index 5618479db..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/binlatticespatialsubdivision/intersection/intersection_slow/Thing.pde +++ /dev/null @@ -1,32 +0,0 @@ -// Daniel Shiffman -// -// April 6, 2006 - -// Simple class describing an ellipse living on our screen - -class Thing { - - float x,y; - boolean highlight; - float r; - - Thing (float x_, float y_) { - x = x_; - y = y_; - highlight = false; - r = random(8) + 1; - } - - void move() { - x += random(-1,1); - y += random(-1,1); - } - - void render() { - noStroke(); - if (highlight) fill(255); - else fill(100); - ellipse(x,y,r,r); - } - -} diff --git a/java/examples/Books/Nature of Code/chp6_agents/binlatticespatialsubdivision/intersection/intersection_slow/intersection_slow.pde b/java/examples/Books/Nature of Code/chp6_agents/binlatticespatialsubdivision/intersection/intersection_slow/intersection_slow.pde deleted file mode 100644 index 5c3beae4e..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/binlatticespatialsubdivision/intersection/intersection_slow/intersection_slow.pde +++ /dev/null @@ -1,59 +0,0 @@ -// Daniel Shiffman -// - -// The old way to do intersection tests, look how slow!! - - -int totalThings = 2000; - -ArrayList a; // ArrayList for all "things" - -void setup() { - size(640,360); - a = new ArrayList(); // Create the list - - // Put 2000 Things in the system - for (int i = 0; i < totalThings; i++) { - a.add(new Thing(random(width),random(height))); - } - -} - -void draw() { - background(0); - fill(255); - noStroke(); - smooth(); - - // Run through the Grid - stroke(255); - for (Thing t : a) { - t.highlight = false; - for (Thing other : a) { - // As long as its not the same one - if (t != other) { - // Check to see if they are touching - // (We could do many other things here besides just intersection tests, such - // as apply forces, etc.) - float d = dist(t.x,t.y,other.x,other.y); - if (d < t.r/2 + other.r/2) { - t.highlight = true; - } - } - } - } - - // Display and move all Things - for (Thing t : a) { - t.render(); - t.move(); - } - - fill(0); - rect(0,height-20,width,20); - fill(255); - text("Framerate: " + int(frameRate),10,height-6); - - - -} diff --git a/java/examples/Books/Nature of Code/chp6_agents/box2d/Flocking_box2d/Boid.pde b/java/examples/Books/Nature of Code/chp6_agents/box2d/Flocking_box2d/Boid.pde deleted file mode 100644 index c46398ee9..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/box2d/Flocking_box2d/Boid.pde +++ /dev/null @@ -1,255 +0,0 @@ -// Flocking -// Daniel Shiffman -// The Nature of Code - -// Boid class -// Methods for Separation, Cohesion, Alignment added - -class Boid { - - // We need to keep track of a Body and a width and height - Body body; - float w; - float h; - - float maxforce; // Maximum steering force - float maxspeed; // Maximum speed - - Boid(PVector loc) { - w = 12; - h = 12; - // Add the box to the box2d world - makeBody(new Vec2(loc.x,loc.y),w,h,new Vec2(0,0),0); - maxspeed = 20; - maxforce = 10; - } - - // This function removes the particle from the box2d world - void killBody() { - box2d.destroyBody(body); - } - - void run(ArrayList boids) { - flock(boids); - borders(); - display(); - } - - // We accumulate a new acceleration each time based on three rules - void flock(ArrayList boids) { - Vec2 sep = separate(boids); // Separation - Vec2 ali = align(boids); // Alignment - Vec2 coh = cohesion(boids); // Cohesion - // Arbitrarily weight these forces - sep.mulLocal(1.5); - ali.mulLocal(1); - coh.mulLocal(1); - // Add the force vectors to acceleration - Vec2 loc = body.getWorldCenter(); - body.applyForce(sep,loc); - body.applyForce(ali,loc); - body.applyForce(coh,loc); - } - - // A method that calculates and applies a steering force towards a target - // STEER = DESIRED MINUS VELOCITY - Vec2 seek(Vec2 target) { - Vec2 loc = body.getWorldCenter(); - Vec2 desired = target.sub(loc); // A vector pointing from the location to the target - - // If the magnitude of desired equals 0, skip out of here - // (We could optimize this to check if x and y are 0 to avoid mag() square root - if (desired.length() == 0) return new Vec2(0,0); - - // Normalize desired and scale to maximum speed - desired.normalize(); - desired.mulLocal(maxspeed); - // Steering = Desired minus Velocity - - Vec2 vel = body.getLinearVelocity(); - Vec2 steer = desired.sub(vel); - - float len = steer.length(); - if (len > maxforce) { - steer.normalize(); - steer.mulLocal(maxforce); - } - return steer; - } - - - - // Drawing the box - void display() { - // We look at each body and get its screen position - Vec2 pos = box2d.getBodyPixelCoord(body); - - // Get its angle of rotation - float a = body.getAngle(); - - rectMode(CENTER); - pushMatrix(); - translate(pos.x,pos.y); - rotate(-a); - fill(175); - strokeWeight(2); - stroke(0); - rect(0,0,w,h); - popMatrix(); - } - - // Wraparound - void borders() { - Vec2 loc = box2d.getBodyPixelCoord(body); - Vec2 vel = body.getLinearVelocity(); - float a = body.getAngularVelocity(); - if (loc.x < -w) { - killBody(); - makeBody(new Vec2(width+w,loc.y),w,h,vel,a); - } else if (loc.y < -w) { - killBody(); - makeBody(new Vec2(loc.x,height+w),w,h,vel,a); - } else if (loc.x > width+w) { - killBody(); - makeBody(new Vec2(-w,loc.y),w,h,vel,a); - } else if (loc.y > height+w) { - killBody(); - makeBody(new Vec2(loc.x,-w),w,h,vel,a); - } - } - - // Separation - // Method checks for nearby boids and steers away - Vec2 separate (ArrayList boids) { - float desiredseparation = box2d.scalarPixelsToWorld(30); - - Vec2 steer = new Vec2(0,0); - int count = 0; - // For every boid in the system, check if it's too close - Vec2 locA = body.getWorldCenter(); - for (Boid other : boids) { - Vec2 locB = other.body.getWorldCenter(); - float d = dist(locA.x,locA.y,locB.x,locB.y); - // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) - if ((d > 0) && (d < desiredseparation)) { - // Calculate vector pointing away from neighbor - Vec2 diff = locA.sub(locB); - diff.normalize(); - diff.mulLocal(1.0/d); // Weight by distance - steer.addLocal(diff); - count++; // Keep track of how many - } - } - // Average -- divide by how many - if (count > 0) { - steer.mulLocal(1.0/count); - } - - // As long as the vector is greater than 0 - if (steer.length() > 0) { - // Implement Reynolds: Steering = Desired - Velocity - steer.normalize(); - steer.mulLocal(maxspeed); - Vec2 vel = body.getLinearVelocity(); - steer.subLocal(vel); - float len = steer.length(); - if (len > maxforce) { - steer.normalize(); - steer.mulLocal(maxforce); - } - } - return steer; - } - - // Alignment - // For every nearby boid in the system, calculate the average velocity - Vec2 align (ArrayList boids) { - float neighbordist = box2d.scalarPixelsToWorld(50); - Vec2 steer = new Vec2(0,0); - int count = 0; - Vec2 locA = body.getWorldCenter(); - for (Boid other : boids) { - Vec2 locB = other.body.getWorldCenter(); - float d = dist(locA.x,locA.y,locB.x,locB.y); - if ((d > 0) && (d < neighbordist)) { - Vec2 vel = other.body.getLinearVelocity(); - steer.addLocal(vel); - count++; - } - } - if (count > 0) { - steer.mulLocal(1.0/count); - } - - // As long as the vector is greater than 0 - if (steer.length() > 0) { - // Implement Reynolds: Steering = Desired - Velocity - steer.normalize(); - steer.mulLocal(maxspeed); - Vec2 vel = body.getLinearVelocity(); - steer.subLocal(vel); - float len = steer.length(); - if (len > maxforce) { - steer.normalize(); - steer.mulLocal(maxforce); - } - } - return steer; - } - - // Cohesion - // For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location - Vec2 cohesion (ArrayList boids) { - float neighbordist = box2d.scalarPixelsToWorld(50); - Vec2 sum = new Vec2(0,0); // Start with empty vector to accumulate all locations - int count = 0; - Vec2 locA = body.getWorldCenter(); - for (Boid other : boids) { - Vec2 locB = other.body.getWorldCenter(); - - float d = dist(locA.x,locA.y,locB.x,locB.y); - if ((d > 0) && (d < neighbordist)) { - sum.addLocal(locB); // Add location - count++; - } - } - if (count > 0) { - sum.mulLocal(1.0/count); - return seek(sum); // Steer towards the location - } - return sum; - } - - // This function adds the rectangle to the box2d world - void makeBody(Vec2 center, float w_, float h_, Vec2 vel, float avel) { - - // Define a polygon (this is what we use for a rectangle) - PolygonShape sd = new PolygonShape(); - float box2dW = box2d.scalarPixelsToWorld(w_/2); - float box2dH = box2d.scalarPixelsToWorld(h_/2); - sd.setAsBox(box2dW, box2dH); - - // Define a fixture - FixtureDef fd = new FixtureDef(); - fd.shape = sd; - // Parameters that affect physics - fd.density = 1; - fd.friction = 0.3; - fd.restitution = 0.5; - - // Define the body and make it from the shape - BodyDef bd = new BodyDef(); - bd.type = BodyType.DYNAMIC; - bd.position.set(box2d.coordPixelsToWorld(center)); - - body = box2d.createBody(bd); - body.createFixture(fd); - - body.setLinearVelocity(vel); - body.setAngularVelocity(avel); - - } - - -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/box2d/Flocking_box2d/Flock.pde b/java/examples/Books/Nature of Code/chp6_agents/box2d/Flocking_box2d/Flock.pde deleted file mode 100644 index b497c279c..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/box2d/Flocking_box2d/Flock.pde +++ /dev/null @@ -1,25 +0,0 @@ -// Flocking -// Daniel Shiffman -// The Nature of Code - -// Flock class -// Does very little, simply manages the ArrayList of all the boids - -class Flock { - ArrayList boids; // An arraylist for all the boids - - Flock() { - boids = new ArrayList(); // Initialize the arraylist - } - - void run() { - for (Boid b : boids) { - b.run(boids); // Passing the entire list of boids to each boid individually - } - } - - void addBoid(Boid b) { - boids.add(b); - } - -} diff --git a/java/examples/Books/Nature of Code/chp6_agents/box2d/Flocking_box2d/Flocking_box2d.pde b/java/examples/Books/Nature of Code/chp6_agents/box2d/Flocking_box2d/Flocking_box2d.pde deleted file mode 100644 index 3a5934e66..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/box2d/Flocking_box2d/Flocking_box2d.pde +++ /dev/null @@ -1,56 +0,0 @@ -// Flocking -// Daniel Shiffman -// The Nature of Code - -// Demonstration of Craig Reynolds' "Flocking" behavior -// See: http://www.red3d.com/cwr/ -// Rules: Cohesion, Separation, Alignment - -// Click mouse to add boids into the system - -import pbox2d.*; -import org.jbox2d.collision.shapes.*; -import org.jbox2d.common.*; -import org.jbox2d.dynamics.*; - -// A reference to our box2d world -PBox2D box2d; - -Flock flock; - -void setup() { - size(640,360); - // Initialize box2d physics and create the world - box2d = new PBox2D(this); - box2d.createWorld(); - // We are setting a custom gravity - box2d.setGravity(0,0); - - flock = new Flock(); - // Add an initial set of boids into the system - for (int i = 0; i < 50; i++) { - flock.addBoid(new Boid(new PVector(random(width),random(height)))); - } - smooth(); -} - -void draw() { - - - // We must always step through time! - box2d.step(); - - background(255); - flock.run(); - -} - -void mousePressed() { - flock.addBoid(new Boid(new PVector(mouseX,mouseY))); -} - -void mouseDragged() { - flock.addBoid(new Boid(new PVector(mouseX,mouseY))); -} - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/Boid.pde b/java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/Boid.pde deleted file mode 100644 index ee361fe01..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/Boid.pde +++ /dev/null @@ -1,181 +0,0 @@ -float swt = 25.0; //sep.mult(25.0f); -float awt = 4.0; //ali.mult(4.0f); -float cwt = 5.0; //coh.mult(5.0f); -float maxspeed = 1; -float maxforce = 0.025; - - -// Flocking -// Daniel Shiffman -// The Nature of Code, Spring 2009 - -// Boid class -// Methods for Separation, Cohesion, Alignment added - -class Boid { - - PVector loc; - PVector vel; - PVector acc; - float r; - - Boid(float x, float y) { - acc = new PVector(0,0); - vel = new PVector(random(-1,1),random(-1,1)); - loc = new PVector(x,y); - r = 2.0; - } - - void run(ArrayList boids) { - flock(boids); - update(); - borders(); - render(); - } - - void applyForce(PVector force) { - // We could add mass here if we want A = F / M - acc.add(force); - } - - // We accumulate a new acceleration each time based on three rules - void flock(ArrayList boids) { - PVector sep = separate(boids); // Separation - PVector ali = align(boids); // Alignment - PVector coh = cohesion(boids); // Cohesion - // Arbitrarily weight these forces - sep.mult(swt); - ali.mult(awt); - coh.mult(cwt); - // Add the force vectors to acceleration - applyForce(sep); - applyForce(ali); - applyForce(coh); - } - - // Method to update location - void update() { - // Update velocity - vel.add(acc); - // Limit speed - vel.limit(maxspeed); - loc.add(vel); - // Reset accelertion to 0 each cycle - acc.mult(0); - } - - // A method that calculates and applies a steering force towards a target - // STEER = DESIRED MINUS VELOCITY - PVector seek(PVector target) { - PVector desired = PVector.sub(target,loc); // A vector pointing from the location to the target - - // Normalize desired and scale to maximum speed - desired.normalize(); - desired.mult(maxspeed); - // Steering = Desired minus Velocity - PVector steer = PVector.sub(desired,vel); - steer.limit(maxforce); // Limit to maximum steering force - - return steer; - } - - void render() { - // Draw a triangle rotated in the direction of velocity - float theta = vel.heading2D() + radians(90); - fill(175); - stroke(0); - pushMatrix(); - translate(loc.x,loc.y); - rotate(theta); - beginShape(TRIANGLES); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(); - popMatrix(); - } - - // Wraparound - void borders() { - if (loc.x < -r) loc.x = width+r; - if (loc.y < -r) loc.y = height+r; - if (loc.x > width+r) loc.x = -r; - if (loc.y > height+r) loc.y = -r; - } - - // Separation - // Method checks for nearby boids and steers away - PVector separate (ArrayList boids) { - float desiredseparation = 25.0; - PVector steer = new PVector(0,0); - int count = 0; - // For every boid in the system, check if it's too close - for (Boid other : boids) { - float d = PVector.dist(loc,other.loc); - // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) - if ((d > 0) && (d < desiredseparation)) { - // Calculate vector pointing away from neighbor - PVector diff = PVector.sub(loc,other.loc); - diff.normalize(); - diff.div(d); // Weight by distance - steer.add(diff); - count++; // Keep track of how many - } - } - // Average -- divide by how many - if (count > 0) { - steer.div((float)count); - // Implement Reynolds: Steering = Desired - Velocity - steer.normalize(); - steer.mult(maxspeed); - steer.sub(vel); - steer.limit(maxforce); - } - return steer; - } - - // Alignment - // For every nearby boid in the system, calculate the average velocity - PVector align (ArrayList boids) { - float neighbordist = 50.0; - PVector steer = new PVector(); - int count = 0; - for (Boid other : boids) { - float d = PVector.dist(loc,other.loc); - if ((d > 0) && (d < neighbordist)) { - steer.add(other.vel); - count++; - } - } - if (count > 0) { - steer.div((float)count); - // Implement Reynolds: Steering = Desired - Velocity - steer.normalize(); - steer.mult(maxspeed); - steer.sub(vel); - steer.limit(maxforce); - } - return steer; - } - - // Cohesion - // For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location - PVector cohesion (ArrayList boids) { - float neighbordist = 50.0; - PVector sum = new PVector(0,0); // Start with empty vector to accumulate all locations - int count = 0; - for (Boid other : boids) { - float d = PVector.dist(loc,other.loc); - if ((d > 0) && (d < neighbordist)) { - sum.add(other.loc); // Add location - count++; - } - } - if (count > 0) { - sum.div((float)count); - return seek(sum); // Steer towards the location - } - return sum; - } -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/Flock.pde b/java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/Flock.pde deleted file mode 100644 index eb7458e5a..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/Flock.pde +++ /dev/null @@ -1,25 +0,0 @@ -// Flocking -// Daniel Shiffman -// The Nature of Code, Spring 2011 - -// Flock class -// Does very little, simply manages the ArrayList of all the boids - -class Flock { - ArrayList boids; // An ArrayList for all the boids - - Flock() { - boids = new ArrayList(); // Initialize the ArrayList - } - - void run() { - for (Boid b : boids) { - b.run(boids); // Passing the entire list of boids to each boid individually - } - } - - void addBoid(Boid b) { - boids.add(b); - } - -} diff --git a/java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/flocking_sliders.pde b/java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/flocking_sliders.pde deleted file mode 100644 index 16314225a..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/flocking_sliders.pde +++ /dev/null @@ -1,60 +0,0 @@ - -// Flocking -// Daniel Shiffman - -// Demonstration of Craig Reynolds' "Flocking" behavior -// See: http://www.red3d.com/cwr/ -// Rules: Cohesion, Separation, Alignment - -// Click mouse to add boids into the system - -import processing.opengl.*; - - -Flock flock; -PVector center; - -boolean showvalues = true; -boolean scrollbar = false; - - -void setup() { - size(1024,768,OPENGL); - setupScrollbars(); - center = new PVector(width/2,height/2); - colorMode(RGB,255,255,255,100); - flock = new Flock(); - // Add an initial set of boids into the system - for (int i = 0; i < 120; i++) { - flock.addBoid(new Boid(width/2,height/2)); - } - smooth(); -} - - -void draw() { - - background(255); - smooth(); - flock.run(); - drawScrollbars(); - - if (mousePressed && !scrollbar) { - flock.addBoid(new Boid(mouseX,mouseY)); - } - - - if (showvalues) { - fill(0); - textAlign(LEFT); - text("Total boids: " + flock.boids.size() + "\n" + "Framerate: " + round(frameRate) + "\nPress any key to show/hide sliders and text\nClick mouse to add more boids",5,100); - } -} - -void keyPressed() { - showvalues = !showvalues; -} - -void mousePressed() { -} - diff --git a/java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/keyPressed.pde b/java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/keyPressed.pde deleted file mode 100644 index b28b04f64..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/keyPressed.pde +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/scrollbar.pde b/java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/scrollbar.pde deleted file mode 100644 index ded631f29..000000000 --- a/java/examples/Books/Nature of Code/chp6_agents/flocking_sliders/scrollbar.pde +++ /dev/null @@ -1,133 +0,0 @@ -// Code based on "Scrollbar" by Casey Reas - -HScrollbar[] hs = new HScrollbar[5];// -String[] labels = {"separation", "alignment","cohesion","maxspeed","maxforce"}; - -int x = 5; -int y = 20; -int w = 50; -int h = 8; -int l = 2; -int spacing = 4; - -void setupScrollbars() { - for (int i = 0; i < hs.length; i++) { - hs[i] = new HScrollbar(x, y + i*(h+spacing), w, h, l); - } - - hs[0].setPos(0.5); - hs[1].setPos(0.5); - hs[2].setPos(0.5); - hs[3].setPos(0.5); - hs[4].setPos(0.05); - -} - -void drawScrollbars() { - //if (showvalues) { - swt = hs[0].getPos()*10.0f; //sep.mult(25.0f); - awt = hs[1].getPos()*2.0f; //sep.mult(25.0f); - cwt = hs[2].getPos()*2.0f; //sep.mult(25.0f); - maxspeed = hs[3].getPos()*10.0f; - maxforce = hs[4].getPos()*0.5; - - - if (showvalues) { - for (int i = 0; i < hs.length; i++) { - hs[i].update(); - hs[i].draw(); - fill(0); - textAlign(LEFT); - text(labels[i],x+w+spacing,y+i*(h+spacing)+spacing); - //text(hs[i].getPos(),x+w+spacing+75,y+i*(h+spacing)+spacing); - } - } -} - - -class HScrollbar -{ - int swidth, sheight; // width and height of bar - int xpos, ypos; // x and y position of bar - float spos, newspos; // x position of slider - int sposMin, sposMax; // max and min values of slider - int loose; // how loose/heavy - boolean over; // is the mouse over the slider? - boolean locked; - float ratio; - - HScrollbar (int xp, int yp, int sw, int sh, int l) { - swidth = sw; - sheight = sh; - int widthtoheight = sw - sh; - ratio = (float)sw / (float)widthtoheight; - xpos = xp; - ypos = yp-sheight/2; - spos = xpos; - newspos = spos; - sposMin = xpos; - sposMax = xpos + swidth - sheight; - loose = l; - } - - void update() { - if(over()) { - over = true; - } - else { - over = false; - } - if(mousePressed && over) { - scrollbar = true; - locked = true; - } - if(!mousePressed) { - locked = false; - scrollbar = false; - } - if(locked) { - newspos = constrain(mouseX-sheight/2, sposMin, sposMax); - } - if(abs(newspos - spos) > 0) { - spos = spos + (newspos-spos)/loose; - } - } - - int constrain(int val, int minv, int maxv) { - return min(max(val, minv), maxv); - } - - boolean over() { - if(mouseX > xpos && mouseX < xpos+swidth && - mouseY > ypos && mouseY < ypos+sheight) { - return true; - } - else { - return false; - } - } - - void draw() { - fill(255); - rectMode(CORNER); - rect(xpos, ypos, swidth, sheight); - if(over || locked) { - fill(153, 102, 0); - } - else { - fill(102, 102, 102); - } - rect(spos, ypos, sheight, sheight); - } - - void setPos(float s) { - spos = xpos + s*(sposMax-sposMin); - newspos = spos; - } - - float getPos() { - // convert spos to be values between - // 0 and the total width of the scrollbar - return ((spos-xpos))/(sposMax-sposMin);// * ratio; - } -} diff --git a/java/examples/Books/Nature of Code/chp7_CA/Ex7_09_HexagonCells/Cell.pde b/java/examples/Books/Nature of Code/chp7_CA/Ex7_09_HexagonCells/Cell.pde deleted file mode 100644 index 3f4a43fb5..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/Ex7_09_HexagonCells/Cell.pde +++ /dev/null @@ -1,38 +0,0 @@ -class Cell { - - float x, y; - float w; - float xoff; - float yoff; - - int state; - - Cell(float x_, float y_, float w_) { - x = x_; - y = y_; - w = w_; - xoff = w/2; - yoff = sin(radians(60))*w; - state = int(random(2)); - } - - - void display() { - - fill(state*255); - stroke(0); - pushMatrix(); - translate(x,y); - beginShape(); - vertex(0, yoff); - vertex(xoff, 0); - vertex(xoff+w, 0); - vertex(2*w, yoff); - vertex(xoff+w, 2*yoff); - vertex(xoff, 2*yoff); - vertex(0, yoff); - endShape(); - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/Ex7_09_HexagonCells/Ex7_09_HexagonCells.pde b/java/examples/Books/Nature of Code/chp7_CA/Ex7_09_HexagonCells/Ex7_09_HexagonCells.pde deleted file mode 100644 index 072897b33..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/Ex7_09_HexagonCells/Ex7_09_HexagonCells.pde +++ /dev/null @@ -1,24 +0,0 @@ -// Daniel Shiffman, Nature of Code -// - -// Outline for game of life -// This is just a grid of hexagons right now - -GOL gol; - -void setup() { - size(800, 200); - smooth(); - gol = new GOL(); -} - -void draw() { - background(255); - gol.display(); -} - -// reset board when mouse is pressed -void mousePressed() { - gol.init(); -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/Ex7_09_HexagonCells/GOL.pde b/java/examples/Books/Nature of Code/chp7_CA/Ex7_09_HexagonCells/GOL.pde deleted file mode 100644 index c72710b1d..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/Ex7_09_HexagonCells/GOL.pde +++ /dev/null @@ -1,40 +0,0 @@ -class GOL { - - float w = 20; - float h = sin(radians(60))*w; - int columns, rows; - - // Game of life board - Cell[][] board; - - - GOL() { - // Initialize rows, columns and set-up arrays - columns = width/int(w*3); - rows = height/int(h); - board = new Cell[columns][rows]; - init(); - } - - void init() { - float h = sin(radians(60))*w; - for (int i = 0; i < columns; i++) { - for (int j = 0; j < rows; j++) { - if (j % 2 == 0) board[i][j] = new Cell(i*w*3, j*h,w); - else board[i][j] = new Cell(i*w*3+w+h/2, j*h, w); - } - } - } - - - - // This is the easy part, just draw the cells, fill 255 for '1', fill 0 for '0' - void display() { - for ( int i = 0; i < columns;i++) { - for ( int j = 0; j < rows;j++) { - board[i][j].display(); - } - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_01_WolframCA_randomizedrules/CA.pde b/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_01_WolframCA_randomizedrules/CA.pde deleted file mode 100644 index c172ad832..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_01_WolframCA_randomizedrules/CA.pde +++ /dev/null @@ -1,95 +0,0 @@ -// Wolfram Cellular Automata -// Daniel Shiffman - -// A class to manage the CA - -class CA { - - int[] cells; // An array of 0s and 1s - int generation; // How many generations? - - int[] ruleset; // An array to store the ruleset, for example {0,1,1,0,1,1,0,1} - - int w = 5; - - CA(int[] r) { - ruleset = r; - cells = new int[width/w]; - restart(); - } - - // Make a random ruleset - void randomize() { - for (int i = 0; i < 8; i++) { - ruleset[i] = int(random(2)); - } - } - - // Reset to generation 0 - void restart() { - for (int i = 0; i < cells.length; i++) { - cells[i] = 0; - } - cells[cells.length/2] = 1; // We arbitrarily start with just the middle cell having a state of "1" - generation = 0; - } - - - // The process of creating the new generation - void generate() { - // First we create an empty array for the new values - int[] nextgen = new int[cells.length]; - // For every spot, determine new state by examing current state, and neighbor states - // Ignore edges that only have one neighor - for (int i = 1; i < cells.length-1; i++) { - int left = cells[i-1]; // Left neighbor state - int me = cells[i]; // Current state - int right = cells[i+1]; // Right neighbor state - nextgen[i] = rules(left, me, right); // Compute next generation state based on ruleset - } - // The current generation is the new generation - cells = nextgen; - generation++; - } - - // This is the easy part, just draw the cells, fill 255 for '1', fill 0 for '0' - void display() { - for (int i = 0; i < cells.length; i++) { - if (cells[i] == 1) fill(0); - else fill(255); - noStroke(); - rect(i*w, generation*w, w, w); - } - } - - // Implementing the Wolfram rules - // This is the concise conversion to binary way - /*int rules (int a, int b, int c) { - String s = "" + a + b + c; - int index = Integer.parseInt(s, 2); - return ruleset[index]; - }*/ - // For JavaScript Mode - int rules (int a, int b, int c) { - if (a == 1 && b == 1 && c == 1) return ruleset[0]; - if (a == 1 && b == 1 && c == 0) return ruleset[1]; - if (a == 1 && b == 0 && c == 1) return ruleset[2]; - if (a == 1 && b == 0 && c == 0) return ruleset[3]; - if (a == 0 && b == 1 && c == 1) return ruleset[4]; - if (a == 0 && b == 1 && c == 0) return ruleset[5]; - if (a == 0 && b == 0 && c == 1) return ruleset[6]; - if (a == 0 && b == 0 && c == 0) return ruleset[7]; - return 0; - } - - // The CA is done if it reaches the bottom of the screen - boolean finished() { - if (generation > height/w) { - return true; - } - else { - return false; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_01_WolframCA_randomizedrules/Ex_7_01_WolframCA_randomizedrules.pde b/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_01_WolframCA_randomizedrules/Ex_7_01_WolframCA_randomizedrules.pde deleted file mode 100644 index 95ebb0808..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_01_WolframCA_randomizedrules/Ex_7_01_WolframCA_randomizedrules.pde +++ /dev/null @@ -1,42 +0,0 @@ -// Wolfram Cellular Automata -// Daniel Shiffman - -// Simple demonstration of a Wolfram 1-dimensional cellular automata -// When the system reaches bottom of the window, it restarts with a new ruleset -// Mouse click restarts as well - -CA ca; // An object to describe a Wolfram elementary Cellular Automata - -int delay = 0; - -void setup() { - size(800, 200); - background(255); - int[] ruleset = { - 0, 1, 0, 1, 1, 0, 1, 0 - }; // An initial rule system - ca = new CA(ruleset); // Initialize CA - frameRate(30); -} - -void draw() { - ca.display(); // Draw the CA - ca.generate(); - - if (ca.finished()) { // If we're done, clear the screen, pick a new ruleset and restart - delay++; - if (delay > 30) { - background(255); - ca.randomize(); - ca.restart(); - delay = 0; - } - } -} - -void mousePressed() { - background(255); - ca.randomize(); - ca.restart(); -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling/CA.pde b/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling/CA.pde deleted file mode 100644 index 545d0bb83..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling/CA.pde +++ /dev/null @@ -1,92 +0,0 @@ -// Wolfram Cellular Automata -// Daniel Shiffman - -// A class to manage the CA - -class CA { - - int generation; // How many generations? - int[] ruleset; // An array to store the ruleset, for example {0,1,1,0,1,1,0,1} - int w = 5; - int[][] matrix; // Store a history of generations in 2D array, not just one - - int cols; - int rows; - - - CA(int[] r) { - ruleset = r; - cols = width/w; - rows = height/w; - matrix = new int[cols][rows]; - restart(); - } - - // Make a random ruleset - void randomize() { - for (int i = 0; i < 8; i++) { - ruleset[i] = int(random(2)); - } - } - - // Reset to generation 0 - void restart() { - for (int i = 0; i < cols; i++) { - for (int j = 0; j < rows; j++) { - matrix[i][j] = 0; - } - } - matrix[cols/2][0] = 1; // We arbitrarily start with just the middle cell having a state of "1" - generation = 0; - } - - - // The process of creating the new generation - void generate() { - - // For every spot, determine new state by examing current state, and neighbor states - // Ignore edges that only have one neighor - for (int i = 0; i < cols; i++) { - int left = matrix[(i+cols-1)%cols][generation%rows]; // Left neighbor state - int me = matrix[i][generation%rows]; // Current state - int right = matrix[(i+1)%cols][generation%rows]; // Right neighbor state - matrix[i][(generation+1)%rows] = rules(left, me, right); // Compute next generation state based on ruleset - } - generation++; - } - - // This is the easy part, just draw the cells, fill 255 for '1', fill 0 for '0' - void display() { - int offset = generation%rows; - - for (int i = 0; i < cols; i++) { - for (int j = 0; j < rows; j++) { - int y = j - offset; - if (y <= 0) y = rows + y; - if (matrix[i][j] == 1) fill(0); - else fill(255); - noStroke(); - rect(i*w, (y-1)*w, w, w); - } - } - } - - // Implementing the Wolfram rules - // This is the concise conversion to binary way - int rules (int a, int b, int c) { - String s = "" + a + b + c; - int index = Integer.parseInt(s, 2); - return ruleset[index]; - } - - // The CA is done if it reaches the bottom of the screen - boolean finished() { - if (generation > height/w) { - return true; - } - else { - return false; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling/Ex_7_04_WolframCA_scrolling.pde b/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling/Ex_7_04_WolframCA_scrolling.pde deleted file mode 100644 index 7c1c0c787..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling/Ex_7_04_WolframCA_scrolling.pde +++ /dev/null @@ -1,34 +0,0 @@ -// Wolfram Cellular Automata -// Daniel Shiffman - -// Simple demonstration of a Wolfram 1-dimensional cellular automata -// with the system scrolling by -// Also implements wrap around - -CA ca; // An object to describe a Wolfram elementary Cellular Automata - - -void setup() { - size(800, 200); - frameRate(30); - background(255); - int[] ruleset = {0,1,1,1,1,0,1,1}; // Rule 222 - //int[] ruleset = {0,1,1,1,1,1,0,1}; // Rule 190 - //int[] ruleset = {0,1,1,1,1,0,0,0}; // Rule 30 - //int[] ruleset = {0,1,1,1,0,1,1,0}; // Rule 110 - - ca = new CA(ruleset); // Initialize CA -} - -void draw() { - ca.display(); // Draw the CA - ca.generate(); -} - -void mousePressed() { - saveFrame("222-####.png"); - //background(255); - //ca.randomize(); - //ca.restart(); -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_110/CA.pde b/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_110/CA.pde deleted file mode 100644 index fdfd10d50..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_110/CA.pde +++ /dev/null @@ -1,104 +0,0 @@ -// Wolfram Cellular Automata -// Daniel Shiffman - -// A class to manage the CA - -class CA { - - int generation; // How many generations? - int[] ruleset; // An array to store the ruleset, for example {0,1,1,0,1,1,0,1} - int w = 5; - int[][] matrix; // Store a history of generations in 2D array, not just one - - int cols; - int rows; - - - CA(int[] r) { - ruleset = r; - cols = width/w; - rows = height/w; - matrix = new int[cols][rows]; - restart(); - } - - // Make a random ruleset - void randomize() { - for (int i = 0; i < 8; i++) { - ruleset[i] = int(random(2)); - } - } - - // Reset to generation 0 - void restart() { - for (int i = 0; i < cols; i++) { - for (int j = 0; j < rows; j++) { - matrix[i][j] = 0; - } - } - matrix[cols/2][0] = 1; // We arbitrarily start with just the middle cell having a state of "1" - generation = 0; - } - - - // The process of creating the new generation - void generate() { - - // For every spot, determine new state by examing current state, and neighbor states - // Ignore edges that only have one neighor - for (int i = 0; i < cols; i++) { - int left = matrix[(i+cols-1)%cols][generation%rows]; // Left neighbor state - int me = matrix[i][generation%rows]; // Current state - int right = matrix[(i+1)%cols][generation%rows]; // Right neighbor state - matrix[i][(generation+1)%rows] = rules(left, me, right); // Compute next generation state based on ruleset - } - generation++; - } - - // This is the easy part, just draw the cells, fill 255 for '1', fill 0 for '0' - void display() { - int offset = generation%rows; - - for (int i = 0; i < cols; i++) { - for (int j = 0; j < rows; j++) { - int y = j - offset; - if (y <= 0) y = rows + y; - if (matrix[i][j] == 1) fill(0); - else fill(255); - noStroke(); - rect(i*w, (y-1)*w, w, w); - } - } - } - - // Implementing the Wolfram rules - // This is the concise conversion to binary way - /*int rules (int a, int b, int c) { - String s = "" + a + b + c; - int index = Integer.parseInt(s, 2); - return ruleset[index]; - }*/ - // For JavaScript Mode - int rules (int a, int b, int c) { - if (a == 1 && b == 1 && c == 1) return ruleset[7]; - if (a == 1 && b == 1 && c == 0) return ruleset[6]; - if (a == 1 && b == 0 && c == 1) return ruleset[5]; - if (a == 1 && b == 0 && c == 0) return ruleset[4]; - if (a == 0 && b == 1 && c == 1) return ruleset[3]; - if (a == 0 && b == 1 && c == 0) return ruleset[2]; - if (a == 0 && b == 0 && c == 1) return ruleset[1]; - if (a == 0 && b == 0 && c == 0) return ruleset[0]; - return 0; - } - - // The CA is done if it reaches the bottom of the screen - boolean finished() { - if (generation > height/w) { - return true; - } - else { - return false; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_110/Ex_7_04_WolframCA_scrolling_110.pde b/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_110/Ex_7_04_WolframCA_scrolling_110.pde deleted file mode 100644 index 034c8cc75..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_110/Ex_7_04_WolframCA_scrolling_110.pde +++ /dev/null @@ -1,26 +0,0 @@ -// Wolfram Cellular Automata -// Daniel Shiffman - -// Simple demonstration of a Wolfram 1-dimensional cellular automata -// with the system scrolling by -// Also implements wrap around - -CA ca; // An object to describe a Wolfram elementary Cellular Automata - - -void setup() { - size(800, 100); - frameRate(30); - background(255); - //int[] ruleset = {0,1,1,1,1,0,1,1}; // Rule 222 - //int[] ruleset = {0,1,1,1,1,1,0,1}; // Rule 190 - //int[] ruleset = {0,1,1,1,1,0,0,0}; // Rule 30 - int[] ruleset = {0,1,1,1,0,1,1,0}; // Rule 110 - - ca = new CA(ruleset); // Initialize CA -} - -void draw() { - ca.display(); // Draw the CA - ca.generate(); -} diff --git a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_190/CA.pde b/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_190/CA.pde deleted file mode 100644 index fdfd10d50..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_190/CA.pde +++ /dev/null @@ -1,104 +0,0 @@ -// Wolfram Cellular Automata -// Daniel Shiffman - -// A class to manage the CA - -class CA { - - int generation; // How many generations? - int[] ruleset; // An array to store the ruleset, for example {0,1,1,0,1,1,0,1} - int w = 5; - int[][] matrix; // Store a history of generations in 2D array, not just one - - int cols; - int rows; - - - CA(int[] r) { - ruleset = r; - cols = width/w; - rows = height/w; - matrix = new int[cols][rows]; - restart(); - } - - // Make a random ruleset - void randomize() { - for (int i = 0; i < 8; i++) { - ruleset[i] = int(random(2)); - } - } - - // Reset to generation 0 - void restart() { - for (int i = 0; i < cols; i++) { - for (int j = 0; j < rows; j++) { - matrix[i][j] = 0; - } - } - matrix[cols/2][0] = 1; // We arbitrarily start with just the middle cell having a state of "1" - generation = 0; - } - - - // The process of creating the new generation - void generate() { - - // For every spot, determine new state by examing current state, and neighbor states - // Ignore edges that only have one neighor - for (int i = 0; i < cols; i++) { - int left = matrix[(i+cols-1)%cols][generation%rows]; // Left neighbor state - int me = matrix[i][generation%rows]; // Current state - int right = matrix[(i+1)%cols][generation%rows]; // Right neighbor state - matrix[i][(generation+1)%rows] = rules(left, me, right); // Compute next generation state based on ruleset - } - generation++; - } - - // This is the easy part, just draw the cells, fill 255 for '1', fill 0 for '0' - void display() { - int offset = generation%rows; - - for (int i = 0; i < cols; i++) { - for (int j = 0; j < rows; j++) { - int y = j - offset; - if (y <= 0) y = rows + y; - if (matrix[i][j] == 1) fill(0); - else fill(255); - noStroke(); - rect(i*w, (y-1)*w, w, w); - } - } - } - - // Implementing the Wolfram rules - // This is the concise conversion to binary way - /*int rules (int a, int b, int c) { - String s = "" + a + b + c; - int index = Integer.parseInt(s, 2); - return ruleset[index]; - }*/ - // For JavaScript Mode - int rules (int a, int b, int c) { - if (a == 1 && b == 1 && c == 1) return ruleset[7]; - if (a == 1 && b == 1 && c == 0) return ruleset[6]; - if (a == 1 && b == 0 && c == 1) return ruleset[5]; - if (a == 1 && b == 0 && c == 0) return ruleset[4]; - if (a == 0 && b == 1 && c == 1) return ruleset[3]; - if (a == 0 && b == 1 && c == 0) return ruleset[2]; - if (a == 0 && b == 0 && c == 1) return ruleset[1]; - if (a == 0 && b == 0 && c == 0) return ruleset[0]; - return 0; - } - - // The CA is done if it reaches the bottom of the screen - boolean finished() { - if (generation > height/w) { - return true; - } - else { - return false; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_190/Ex_7_04_WolframCA_scrolling_190.pde b/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_190/Ex_7_04_WolframCA_scrolling_190.pde deleted file mode 100644 index ea30685db..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_190/Ex_7_04_WolframCA_scrolling_190.pde +++ /dev/null @@ -1,27 +0,0 @@ -// Wolfram Cellular Automata -// Daniel Shiffman - -// Simple demonstration of a Wolfram 1-dimensional cellular automata -// with the system scrolling by -// Also implements wrap around - -CA ca; // An object to describe a Wolfram elementary Cellular Automata - - -void setup() { - size(800, 100); - frameRate(30); - background(255); - //int[] ruleset = {0,1,1,1,1,0,1,1}; // Rule 222 - int[] ruleset = {0,1,1,1,1,1,0,1}; // Rule 190 - //int[] ruleset = {0,1,1,1,1,0,0,0}; // Rule 30 - //int[] ruleset = {0,1,1,1,0,1,1,0}; // Rule 110 - - ca = new CA(ruleset); // Initialize CA -} - -void draw() { - ca.display(); // Draw the CA - ca.generate(); -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_222/CA.pde b/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_222/CA.pde deleted file mode 100644 index fdfd10d50..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_222/CA.pde +++ /dev/null @@ -1,104 +0,0 @@ -// Wolfram Cellular Automata -// Daniel Shiffman - -// A class to manage the CA - -class CA { - - int generation; // How many generations? - int[] ruleset; // An array to store the ruleset, for example {0,1,1,0,1,1,0,1} - int w = 5; - int[][] matrix; // Store a history of generations in 2D array, not just one - - int cols; - int rows; - - - CA(int[] r) { - ruleset = r; - cols = width/w; - rows = height/w; - matrix = new int[cols][rows]; - restart(); - } - - // Make a random ruleset - void randomize() { - for (int i = 0; i < 8; i++) { - ruleset[i] = int(random(2)); - } - } - - // Reset to generation 0 - void restart() { - for (int i = 0; i < cols; i++) { - for (int j = 0; j < rows; j++) { - matrix[i][j] = 0; - } - } - matrix[cols/2][0] = 1; // We arbitrarily start with just the middle cell having a state of "1" - generation = 0; - } - - - // The process of creating the new generation - void generate() { - - // For every spot, determine new state by examing current state, and neighbor states - // Ignore edges that only have one neighor - for (int i = 0; i < cols; i++) { - int left = matrix[(i+cols-1)%cols][generation%rows]; // Left neighbor state - int me = matrix[i][generation%rows]; // Current state - int right = matrix[(i+1)%cols][generation%rows]; // Right neighbor state - matrix[i][(generation+1)%rows] = rules(left, me, right); // Compute next generation state based on ruleset - } - generation++; - } - - // This is the easy part, just draw the cells, fill 255 for '1', fill 0 for '0' - void display() { - int offset = generation%rows; - - for (int i = 0; i < cols; i++) { - for (int j = 0; j < rows; j++) { - int y = j - offset; - if (y <= 0) y = rows + y; - if (matrix[i][j] == 1) fill(0); - else fill(255); - noStroke(); - rect(i*w, (y-1)*w, w, w); - } - } - } - - // Implementing the Wolfram rules - // This is the concise conversion to binary way - /*int rules (int a, int b, int c) { - String s = "" + a + b + c; - int index = Integer.parseInt(s, 2); - return ruleset[index]; - }*/ - // For JavaScript Mode - int rules (int a, int b, int c) { - if (a == 1 && b == 1 && c == 1) return ruleset[7]; - if (a == 1 && b == 1 && c == 0) return ruleset[6]; - if (a == 1 && b == 0 && c == 1) return ruleset[5]; - if (a == 1 && b == 0 && c == 0) return ruleset[4]; - if (a == 0 && b == 1 && c == 1) return ruleset[3]; - if (a == 0 && b == 1 && c == 0) return ruleset[2]; - if (a == 0 && b == 0 && c == 1) return ruleset[1]; - if (a == 0 && b == 0 && c == 0) return ruleset[0]; - return 0; - } - - // The CA is done if it reaches the bottom of the screen - boolean finished() { - if (generation > height/w) { - return true; - } - else { - return false; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_222/Ex_7_04_WolframCA_scrolling_222.pde b/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_222/Ex_7_04_WolframCA_scrolling_222.pde deleted file mode 100644 index 69af02447..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_222/Ex_7_04_WolframCA_scrolling_222.pde +++ /dev/null @@ -1,27 +0,0 @@ -// Wolfram Cellular Automata -// Daniel Shiffman - -// Simple demonstration of a Wolfram 1-dimensional cellular automata -// with the system scrolling by -// Also implements wrap around - -CA ca; // An object to describe a Wolfram elementary Cellular Automata - - -void setup() { - size(800, 100); - frameRate(30); - background(255); - int[] ruleset = {0,1,1,1,1,0,1,1}; // Rule 222 - //int[] ruleset = {0,1,1,1,1,1,0,1}; // Rule 190 - //int[] ruleset = {0,1,1,1,1,0,0,0}; // Rule 30 - //int[] ruleset = {0,1,1,1,0,1,1,0}; // Rule 110 - - ca = new CA(ruleset); // Initialize CA -} - -void draw() { - ca.display(); // Draw the CA - ca.generate(); -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_30/CA.pde b/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_30/CA.pde deleted file mode 100644 index 0999f18b1..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_30/CA.pde +++ /dev/null @@ -1,103 +0,0 @@ -// Wolfram Cellular Automata -// Daniel Shiffman - -// A class to manage the CA - -class CA { - - int generation; // How many generations? - int[] ruleset; // An array to store the ruleset, for example {0,1,1,0,1,1,0,1} - int w = 5; - int[][] matrix; // Store a history of generations in 2D array, not just one - - int cols; - int rows; - - - CA(int[] r) { - ruleset = r; - cols = width/w; - rows = height/w; - matrix = new int[cols][rows]; - restart(); - } - - // Make a random ruleset - void randomize() { - for (int i = 0; i < 8; i++) { - ruleset[i] = int(random(2)); - } - } - - // Reset to generation 0 - void restart() { - for (int i = 0; i < cols; i++) { - for (int j = 0; j < rows; j++) { - matrix[i][j] = 0; - } - } - matrix[cols/2][0] = 1; // We arbitrarily start with just the middle cell having a state of "1" - generation = 0; - } - - - // The process of creating the new generation - void generate() { - - // For every spot, determine new state by examing current state, and neighbor states - // Ignore edges that only have one neighor - for (int i = 0; i < cols; i++) { - int left = matrix[(i+cols-1)%cols][generation%rows]; // Left neighbor state - int me = matrix[i][generation%rows]; // Current state - int right = matrix[(i+1)%cols][generation%rows]; // Right neighbor state - matrix[i][(generation+1)%rows] = rules(left, me, right); // Compute next generation state based on ruleset - } - generation++; - } - - // This is the easy part, just draw the cells, fill 255 for '1', fill 0 for '0' - void display() { - int offset = generation%rows; - - for (int i = 0; i < cols; i++) { - for (int j = 0; j < rows; j++) { - int y = j - offset; - if (y <= 0) y = rows + y; - if (matrix[i][j] == 1) fill(0); - else fill(255); - noStroke(); - rect(i*w, (y-1)*w, w, w); - } - } - } - // Implementing the Wolfram rules - // This is the concise conversion to binary way - /*int rules (int a, int b, int c) { - String s = "" + a + b + c; - int index = Integer.parseInt(s, 2); - return ruleset[index]; - }*/ - // For JavaScript Mode - int rules (int a, int b, int c) { - if (a == 1 && b == 1 && c == 1) return ruleset[7]; - if (a == 1 && b == 1 && c == 0) return ruleset[6]; - if (a == 1 && b == 0 && c == 1) return ruleset[5]; - if (a == 1 && b == 0 && c == 0) return ruleset[4]; - if (a == 0 && b == 1 && c == 1) return ruleset[3]; - if (a == 0 && b == 1 && c == 0) return ruleset[2]; - if (a == 0 && b == 0 && c == 1) return ruleset[1]; - if (a == 0 && b == 0 && c == 0) return ruleset[0]; - return 0; - } - - // The CA is done if it reaches the bottom of the screen - boolean finished() { - if (generation > height/w) { - return true; - } - else { - return false; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_30/Ex_7_04_WolframCA_scrolling_30.pde b/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_30/Ex_7_04_WolframCA_scrolling_30.pde deleted file mode 100644 index 044451336..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/Exercise_7_04_WolframCA_scrolling_30/Ex_7_04_WolframCA_scrolling_30.pde +++ /dev/null @@ -1,27 +0,0 @@ -// Wolfram Cellular Automata -// Daniel Shiffman - -// Simple demonstration of a Wolfram 1-dimensional cellular automata -// with the system scrolling by -// Also implements wrap around - -CA ca; // An object to describe a Wolfram elementary Cellular Automata - - -void setup() { - size(800, 100); - frameRate(30); - background(255); - //int[] ruleset = {0,1,1,1,1,0,1,1}; // Rule 222 - //int[] ruleset = {0,1,1,1,1,1,0,1}; // Rule 190 - int[] ruleset = {0,1,1,1,1,0,0,0}; // Rule 30 - //int[] ruleset = {0,1,1,1,0,1,1,0}; // Rule 110 - - ca = new CA(ruleset); // Initialize CA -} - -void draw() { - ca.display(); // Draw the CA - ca.generate(); -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/Figure_7_17_cells/Figure_7_17_cells.pde b/java/examples/Books/Nature of Code/chp7_CA/Figure_7_17_cells/Figure_7_17_cells.pde deleted file mode 100644 index 81ec31d42..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/Figure_7_17_cells/Figure_7_17_cells.pde +++ /dev/null @@ -1,28 +0,0 @@ - -size(1800,90); - -int w = 90; - -int total = width/w; - -int[] cells = {1,0,1,0,0,0,0,1,0,1,1,1,0,0,0,1,1,1,0,0}; - - -print("int[] cells = {"); -for (int i = 0; i < cells.length; i++) { - if (cells[i] == 0) fill(255); - else fill(64); - stroke(0); - rect(i*w,0,w-1,w-1); - print(cells[i] +","); -} - -saveFrame("cells.png"); - - - - - - - - diff --git a/java/examples/Books/Nature of Code/chp7_CA/Figure_7_17_cells/cells.tif b/java/examples/Books/Nature of Code/chp7_CA/Figure_7_17_cells/cells.tif deleted file mode 100644 index 38ef13501fddfbe9a3b66bc778d2b839a9253b66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 486768 zcmeI!L5?0)6-427f=C!L0QSHt*g!VG5*RUN@jyE^(vhxShD_?~DDBd3Tb9l}RsDYX z<>Rj(A0Iz|{Ndx@AHVxdUq1i;`t8TBzx?#`=eIB4^2gsl^AEq~ufO-NFTel(`469; z|M7o+_s5SffBOFU=b!rW=ltEjeE%~){o|is|BcUo^Xq@U5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0;r|4HC)zJ4X}jro6k{Yu~)4QhNNz>U@d4KzxinH!ge6}6(Z;#>9; zw!J_DjS^_~Go|Z+1{x*MY(?*G^poYxjb7i1-reXY%UM%2<>fy&xbfR=ync7>b3b8w zaWpQCF3ED{1~*>*dvBBs8ka`9vz)DHuaCy1(e5l~E86R$acQ(W%h`(d`kJCC^`V&? z+^7%DRuqjAXy(SH(Ir{V+~CH`fA5WwLF3YBcb2mi?e)>PG}@izY(;y0G%k&HXE|HZ zUSCr*r9L!sgB$gs*@~i30?pjGG`b|qnH$`A`R~0^GH6^H?ap$xqP;#Emqxp@oULfD zkH)3Z?ks03+UskIrqqXKZg8VMG+R+LN}!n=mqwRlIdg*>FaNzaN(PNfqup7~RkZu z%#BN!WdLv^&e$iuU?wTpI1pa<-zqzNTnOeQ4$e zH|j&P6-A>2nz?albV-&oH@NZg-+QBE(6}_(o#kvrdwn!6jdo`_ThU%0jZ355Sue4yR)3FXs?gPrP1yzXDiz4 zqj71pJImRM_WGKlDfOY58{DW5%~lkR5@_berO_o>&fMU}%YW~Ul0oCrXm^&g747xW zxHQ_GPG}@izY(;y0P0^J4(98{P)Q4s(ibe@E zbK}zJk}PL#aO35__eRN}acQ(W%h`(d`eU6SR@4Q{;r_ueQOG%k&HXE|HZULTE1qup7~RO(U(xKSUPttc8L(9DfXqf4@!xxtN>|K1xVgT|%N?ks03+UuinX|y}b*^2i1 zXj~fY&T_V*y}qVsN_}YN1~=+MvlT_71e&>VX>>`JGdH;L^51)-WYD-Y+MVTWMSFcT zE{%3)Ia|?QAB{_+-C537wAa@ZO{ovf+~7uiXtttglt42#E{!h9a^?m%UjBP;lnfe| zM!U0|t!S^0#--8jEN3g)>!WdLv^&e$iuU@NqAB&EnH$`w56xB-jS^_)#--6ES;>2jgmp*(r9;hXm^&g747xWxHQ_G#1fo5)88eNj*%nfe5{P*4{88j}9c4s+T(Ow^o zOQYRc&Q`S7N8{3Hcb2mi?e#T9Q|d!AH@HzBnyn}rCD6=`OQTD&oVme`m;c@yC4uZXp)Q4tnaHBpnTTwJhpqU$&MwetcbAuZ%|GhU#28~Oj-C537wAV-D z(r9;D~D1l~fTpC@H<;)Fk zy!`jxC>b;^jdo`_ThU%0jZ355ShXm^&g747vkMN{fSGdH+VADXQw8YR%o zjZ33TvYffWjhFx48zqCrrP1yzXDiz4qj71pJImRM_WEdC8tu+O->?MWY0oxp8T9NtQD=xbgDed!uB~xHQ_G*dvBBs8ka`9vz)DHuaCy1(e5l~E86R$ zacQ(W%h`(d`kJCC^`V&?+^7%DRuqjAXy(SH(Ir{V+~CH`fA5WwLF3YBcb2mi?e)>P zG}@izY(;y0G%k&HXE|HZUSCr*r9L!sgB$gs*@~i30?pjGG`b|qnH$`A`R~0^GH6^H z?ap$xqP;#Emqxp@oULfDkH)3Z?ks03+UskIrqqXKZg8VMG+R+LN}!n=mqwRlIdg*> zFaNzaN(PNfqup7~RkZu%#BN!WdLv^&e$iuU?w zTpI1pa<-zqzNTnOeQ4$eH|j&P6-A>2nz?albV-&oH@NZg-+QBE(6}_(o#kvrdwn!6 zjdo`_ThU%0jZ355Sue4 zyR)3FXs?gPrP1yzXDiz4qj71pJImRM_WGKlDfOY58{DW5%~lkR5@_berO_o>&fMU} z%YW~Ul0oCrXm^&g747xWxHQ_GPG}@izY(;y0 zP0^J4(98{P)Q4s(ibe@EbK}zJk}PL#aO35__eRN}acQ(W%h`(d`eU6SR@4Q{;r_ueQOG%k&HXE|HZULTE1 zqup7~RO(U(xKSUPttc8L(9DfXqf4@!xxtN>|K1xVgT|%N z?ks03+UuinX|y}b*^2i1Xj~fY&T_V*y}qVsN_}YN1~=+MvlT_71e&>VX>>`JGdH;L z^51)-WYD-Y+MVTWMSFcTE{%3)Ia|?QAB{_+-C537wAa@ZO{ovf+~7uiXtttglt42# zE{!h9a^?m%UjBP;lnfe|M!U0|t!S^0#--8jEN3g)>!WdLv^&e$iuU@NqAB&EnH$`w z56xB-jS^_)#--6ES;>2jgmp*(r9;h zXm^&g747xWxHQ_G#1fo5)88eNj*%nfe5 z{P*4{88j}9c4s+T(Ow^oOQYRc&Q`S7N8{3Hcb2mi?e#T9Q|d!AH@HzBnyn}rCD6=` zOQTD&oVme`m;c@yC4uZXp)Q4tnaHBpnTTwJhpqU$&MwetcbAuZ% z|GhU#28~Oj-C537wAV-D(r9;D~D1l~fTpC@H<;)Fky!`jxC>b;^jdo`_ThU%0jZ355ShXm^&g747vk zMN{fSGdH+VADXQw8YR%ojZ33TvYffWjhFx48zqCrrP1yzXDiz4qj71pJImRM_WEdC z8tu+O->?MWY0oxp8T9NtQD=xbgDed!uB~xHQ_G*dvBBs8ka`9 zvz)DHuaCy1(e5l~E86R$acQ(W%h`(d`kJCC^`V&?+^7%DRuqjAXy(SH(Ir{V+~CH` zfA5WwLF3YBcb2mi?e)>PG}@izY(;y0G%k&HXE|HZUSCr*r9L!sgB$gs*@~i30?pjG zG`b|qnH$`A`R~0^GH6^H?ap$xqP;#Emqxp@oULfDkH)3Z?ks03+UskIrqqXKZg8VM zG+R+LN}!n=mqwRlIdg*>FaNzaN(PNfqup7~RkZu%#BN!WdLv^&e$iuU?wTpI1pa<-zqzNTnOeQ4$eH|j&P6-A>2nz?albV-&oH@NZg z-+QBE(6}_(o#kvrdwn!6jdo`_ThU%0jZ355Sue4yR)3FXs?gPrP1yzXDiz4qj71pJImRM_WGKlDfOY58{DW5 z%~lkR5@_berO_o>&fMU}%YW~Ul0oCrXm^&g747xWxHQ_GPG}@izY(;y0P0^J4(98{P)Q4s(ibe@EbK}zJk}PL#aO35__eRN}acQ(W z%h`(d`eU6SR@4Q{;r z_ueQOG%k&HXE|HZULTE1qup7~RO(U(xKSUPttc8L(9DfX zqf4@!xxtN>|K1xVgT|%N?ks03+UuinX|y}b*^2i1Xj~fY&T_V*y}qVsN_}YN1~=+M zvlT_71e&>VX>>`JGdH;L^51)-WYD-Y+MVTWMSFcTE{%3)Ia|?QAB{_+-C537wAa@Z zO{ovf+~7uiXtttglt42#E{!h9a^?m%UjBP;lnfe|M!U0|t!S^0#--8jEN3g)>!WdL zv^&e$iuU@NqAB&EnH$`w56xB-jS^_)#--6ES;>2jgmp*(r9;hXm^&g747xWxHQ_G#1fo5)88eNj*%nfe5{P*4{88j}9c4s+T(Ow^oOQYRc&Q`S7N8{3Hcb2mi?e#T9 zQ|d!AH@HzBnyn}rCD6=`OQTD&oVme`m;c@yC4 3)) next[x][y] = 0; // Overpopulation - else if ((board[x][y] == 0) && (neighbors == 3)) next[x][y] = 1; // Reproduction - else next[x][y] = board[x][y]; // Stasis - } - } - - // Next is now our board - board = next; - } - - // This is the easy part, just draw the cells, fill 255 for '1', fill 0 for '0' - void display() { - for ( int i = 0; i < columns;i++) { - for ( int j = 0; j < rows;j++) { - if ((board[i][j] == 1)) fill(0); - else fill(255); - stroke(0); - rect(i*w, j*w, w, w); - } - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/GameOfLifeWrapAround/GameOfLifeWrapAround.pde b/java/examples/Books/Nature of Code/chp7_CA/GameOfLifeWrapAround/GameOfLifeWrapAround.pde deleted file mode 100644 index 97d409a1c..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/GameOfLifeWrapAround/GameOfLifeWrapAround.pde +++ /dev/null @@ -1,31 +0,0 @@ -// Daniel Shiffman, Nature of Code -// - -// A basic implementation of John Conway's Game of Life CA -// how could this be improved to use object oriented programming? -// think of it as similar to our particle system, with a "cell" class -// to describe each individual cell and a "cellular automata" class -// to describe a collection of cells - -// Cells wrap around - -GOL gol; - -void setup() { - size(400, 400); - smooth(); - gol = new GOL(); -} - -void draw() { - background(255); - - gol.generate(); - gol.display(); -} - -// reset board when mouse is pressed -void mousePressed() { - gol.init(); -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/HexagonCells/Cell.pde b/java/examples/Books/Nature of Code/chp7_CA/HexagonCells/Cell.pde deleted file mode 100644 index 3f4a43fb5..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/HexagonCells/Cell.pde +++ /dev/null @@ -1,38 +0,0 @@ -class Cell { - - float x, y; - float w; - float xoff; - float yoff; - - int state; - - Cell(float x_, float y_, float w_) { - x = x_; - y = y_; - w = w_; - xoff = w/2; - yoff = sin(radians(60))*w; - state = int(random(2)); - } - - - void display() { - - fill(state*255); - stroke(0); - pushMatrix(); - translate(x,y); - beginShape(); - vertex(0, yoff); - vertex(xoff, 0); - vertex(xoff+w, 0); - vertex(2*w, yoff); - vertex(xoff+w, 2*yoff); - vertex(xoff, 2*yoff); - vertex(0, yoff); - endShape(); - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/HexagonCells/GOL.pde b/java/examples/Books/Nature of Code/chp7_CA/HexagonCells/GOL.pde deleted file mode 100644 index c72710b1d..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/HexagonCells/GOL.pde +++ /dev/null @@ -1,40 +0,0 @@ -class GOL { - - float w = 20; - float h = sin(radians(60))*w; - int columns, rows; - - // Game of life board - Cell[][] board; - - - GOL() { - // Initialize rows, columns and set-up arrays - columns = width/int(w*3); - rows = height/int(h); - board = new Cell[columns][rows]; - init(); - } - - void init() { - float h = sin(radians(60))*w; - for (int i = 0; i < columns; i++) { - for (int j = 0; j < rows; j++) { - if (j % 2 == 0) board[i][j] = new Cell(i*w*3, j*h,w); - else board[i][j] = new Cell(i*w*3+w+h/2, j*h, w); - } - } - } - - - - // This is the easy part, just draw the cells, fill 255 for '1', fill 0 for '0' - void display() { - for ( int i = 0; i < columns;i++) { - for ( int j = 0; j < rows;j++) { - board[i][j].display(); - } - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/HexagonCells/HexagonCells.pde b/java/examples/Books/Nature of Code/chp7_CA/HexagonCells/HexagonCells.pde deleted file mode 100644 index 2a42cdc5b..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/HexagonCells/HexagonCells.pde +++ /dev/null @@ -1,24 +0,0 @@ -// Daniel Shiffman, Nature of Code -// - -// Outline for game of life -// This is just a grid of hexagons right now - -GOL gol; - -void setup() { - size(600, 600); - smooth(); - gol = new GOL(); -} - -void draw() { - background(255); - gol.display(); -} - -// reset board when mouse is pressed -void mousePressed() { - gol.init(); -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/NOC_7_01_WolframCA_figures/CA.pde b/java/examples/Books/Nature of Code/chp7_CA/NOC_7_01_WolframCA_figures/CA.pde deleted file mode 100644 index adb77ee3e..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/NOC_7_01_WolframCA_figures/CA.pde +++ /dev/null @@ -1,92 +0,0 @@ -// Wolfram Cellular Automata -// Daniel Shiffman - -// A class to manage the CA - -class CA { - - int[] cells; // An array of 0s and 1s - int generation; // How many generations? - - int[] ruleset; // An array to store the ruleset, for example {0,1,1,0,1,1,0,1} - - CA(int[] r) { - ruleset = r; - cells = new int[width/scl]; - restart(); - } - - CA() { - scl = 1; - cells = new int[width/scl]; - randomize(); - restart(); - } - - // Set the rules of the CA - void setRules(int[] r) { - ruleset = r; - } - - // Make a random ruleset - void randomize() { - for (int i = 0; i < 8; i++) { - ruleset[i] = int(random(2)); - } - } - - // Reset to generation 0 - void restart() { - for (int i = 0; i < cells.length; i++) { - cells[i] = 0; - } - cells[cells.length/2] = 1; // We arbitrarily start with just the middle cell having a state of "1" - generation = 0; - } - - // The process of creating the new generation - void generate() { - // First we create an empty array for the new values - int[] nextgen = new int[cells.length]; - // For every spot, determine new state by examing current state, and neighbor states - // Ignore edges that only have one neighor - for (int i = 1; i < cells.length-1; i++) { - int left = cells[i-1]; // Left neighbor state - int me = cells[i]; // Current state - int right = cells[i+1]; // Right neighbor state - nextgen[i] = rules(left, me, right); // Compute next generation state based on ruleset - } - // The current generation is the new generation - cells = nextgen; - generation++; - } - - // This is the easy part, just draw the cells, fill 255 for '1', fill 0 for '0' - void render() { - for (int i = 0; i < cells.length; i++) { - if (cells[i] == 1) fill(0); - else fill(255); - stroke(0); - rect(i*scl, generation*scl, scl, scl); - } - } - - // Implementing the Wolfram rules - // Could be improved and made more concise, but here we can explicitly see what is going on for each case - int rules (int a, int b, int c) { - String s = "" + a + b + c; - int index = Integer.parseInt(s,2); - return ruleset[index]; - } - - // The CA is done if it reaches the bottom of the screen - boolean finished() { - if (generation > height/scl) { - return true; - } - else { - return false; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/NOC_7_01_WolframCA_figures/_7_01_WolframCA_figures.pde b/java/examples/Books/Nature of Code/chp7_CA/NOC_7_01_WolframCA_figures/_7_01_WolframCA_figures.pde deleted file mode 100644 index a824998f2..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/NOC_7_01_WolframCA_figures/_7_01_WolframCA_figures.pde +++ /dev/null @@ -1,35 +0,0 @@ -// Wolfram Cellular Automata -// Daniel Shiffman - -// Simple demonstration of a Wolfram 1-dimensional cellular automata -// When the system reaches bottom of the window, it restarts with a new ruleset -// Mouse click restarts as well - - -CA ca; // An instance object to describe the Wolfram basic Cellular Automata - -int scl = 20; - -void setup() { - size(1800,600); - background(255); - //int[] ruleset = {0,1,0,1,1,0,1,0}; // 90 - int[] ruleset = {0,1,1,1,1,0,1,1}; // An initial rule system - ca = new CA(ruleset); // Initialize CA -} - -void draw() { - ca.render(); // Draw the CA - ca.generate(); // Generate the next level - - if (ca.finished()) { // If we're done, clear the screen, pick a new ruleset and restart - saveFrame("rule222.png"); - noLoop(); - } -} - -void mousePressed() { - background(255); - ca.randomize(); - ca.restart(); -} diff --git a/java/examples/Books/Nature of Code/chp7_CA/NOC_7_01_WolframCA_simple/CA.pde b/java/examples/Books/Nature of Code/chp7_CA/NOC_7_01_WolframCA_simple/CA.pde deleted file mode 100644 index 654b06645..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/NOC_7_01_WolframCA_simple/CA.pde +++ /dev/null @@ -1,65 +0,0 @@ -// Wolfram Cellular Automata -// Daniel Shiffman - -// A class to manage the CA - -class CA { - - int[] cells; // An array of 0s and 1s - int generation; // How many generations? - - int[] ruleset = {0, 1, 0, 1, 1, 0, 1, 0}; // An array to store the ruleset, for example {0,1,1,0,1,1,0,1} - - int w = 10; - - CA() { - cells = new int[width/w]; - for (int i = 0; i < cells.length; i++) { - cells[i] = 0; - } - cells[cells.length/2] = 1; // We arbitrarily start with just the middle cell having a state of "1" - generation = 0; - } - - // The process of creating the new generation - void generate() { - // First we create an empty array for the new values - int[] nextgen = new int[cells.length]; - // For every spot, determine new state by examing current state, and neighbor states - // Ignore edges that only have one neighor - for (int i = 1; i < cells.length-1; i++) { - int left = cells[i-1]; // Left neighbor state - int me = cells[i]; // Current state - int right = cells[i+1]; // Right neighbor state - nextgen[i] = rules(left, me, right); // Compute next generation state based on ruleset - } - // The current generation is the new generation - cells = nextgen; - generation++; - } - - // This is the easy part, just draw the cells, fill 255 for '1', fill 0 for '0' - void display() { - for (int i = 0; i < cells.length; i++) { - if (cells[i] == 1) fill(0); - else fill(255); - noStroke(); - rect(i*w, generation*w, w, w); - } - } - - // Implementing the Wolfram rules - // Could be improved and made more concise, but here we can explicitly see what is going on for each case - int rules (int a, int b, int c) { - if (a == 1 && b == 1 && c == 1) return ruleset[0]; - if (a == 1 && b == 1 && c == 0) return ruleset[1]; - if (a == 1 && b == 0 && c == 1) return ruleset[2]; - if (a == 1 && b == 0 && c == 0) return ruleset[3]; - if (a == 0 && b == 1 && c == 1) return ruleset[4]; - if (a == 0 && b == 1 && c == 0) return ruleset[5]; - if (a == 0 && b == 0 && c == 1) return ruleset[6]; - if (a == 0 && b == 0 && c == 0) return ruleset[7]; - return 0; - } -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/NOC_7_01_WolframCA_simple/_7_01_WolframCA_simple.pde b/java/examples/Books/Nature of Code/chp7_CA/NOC_7_01_WolframCA_simple/_7_01_WolframCA_simple.pde deleted file mode 100644 index 61020ce67..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/NOC_7_01_WolframCA_simple/_7_01_WolframCA_simple.pde +++ /dev/null @@ -1,21 +0,0 @@ -// Wolfram Cellular Automata -// Daniel Shiffman - -// Simple demonstration of a Wolfram 1-dimensional cellular automata - -CA ca; // An instance object to describe the Wolfram basic Cellular Automata - - -void setup() { - size(800, 400); - background(255); - ca = new CA(); // Initialize CA -} - -void draw() { - ca.display(); // Draw the CA - if (ca.generation < height/ca.w) { - ca.generate(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/NOC_7_02_GameOfLifeOOP/Cell.pde b/java/examples/Books/Nature of Code/chp7_CA/NOC_7_02_GameOfLifeOOP/Cell.pde deleted file mode 100644 index 86ba100b6..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/NOC_7_02_GameOfLifeOOP/Cell.pde +++ /dev/null @@ -1,36 +0,0 @@ -class Cell { - - float x, y; - float w; - - int state; - int previous; - - Cell(float x_, float y_, float w_) { - x = x_; - y = y_; - w = w_; - - state = int(random(2)); - previous = state; - } - - void savePrevious() { - previous = state; - } - - void newState(int s) { - state = s; - } - - void display() { - if (previous == 0 && state == 1) fill(0,0,255); - else if (state == 1) fill(0); - else if (previous == 1 && state == 0) fill(255,0,0); - else fill(255); - stroke(0); - rect(x, y, w, w); - } -} - - diff --git a/java/examples/Books/Nature of Code/chp7_CA/NOC_7_02_GameOfLifeOOP/GOL.pde b/java/examples/Books/Nature of Code/chp7_CA/NOC_7_02_GameOfLifeOOP/GOL.pde deleted file mode 100644 index f7c13d486..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/NOC_7_02_GameOfLifeOOP/GOL.pde +++ /dev/null @@ -1,69 +0,0 @@ -class GOL { - - int w = 8; - int columns, rows; - - // Game of life board - Cell[][] board; - - - GOL() { - // Initialize rows, columns and set-up arrays - columns = width/w; - rows = height/w; - board = new Cell[columns][rows]; - init(); - } - - void init() { - for (int i = 0; i < columns; i++) { - for (int j = 0; j < rows; j++) { - board[i][j] = new Cell(i*w, j*w, w); - } - } - } - - // The process of creating the new generation - void generate() { - for ( int i = 0; i < columns;i++) { - for ( int j = 0; j < rows;j++) { - board[i][j].savePrevious(); - } - } - - - // Loop through every spot in our 2D array and check spots neighbors - for (int x = 0; x < columns; x++) { - for (int y = 0; y < rows; y++) { - - // Add up all the states in a 3x3 surrounding grid - int neighbors = 0; - for (int i = -1; i <= 1; i++) { - for (int j = -1; j <= 1; j++) { - neighbors += board[(x+i+columns)%columns][(y+j+rows)%rows].previous; - } - } - - // A little trick to subtract the current cell's state since - // we added it in the above loop - neighbors -= board[x][y].previous; - - // Rules of Life - if ((board[x][y].state == 1) && (neighbors < 2)) board[x][y].newState(0); // Loneliness - else if ((board[x][y].state == 1) && (neighbors > 3)) board[x][y].newState(0); // Overpopulation - else if ((board[x][y].state == 0) && (neighbors == 3)) board[x][y].newState(1); // Reproduction - // else do nothing! - } - } - } - - // This is the easy part, just draw the cells, fill 255 for '1', fill 0 for '0' - void display() { - for ( int i = 0; i < columns;i++) { - for ( int j = 0; j < rows;j++) { - board[i][j].display(); - } - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/NOC_7_02_GameOfLifeOOP/_7_02_GameOfLifeOOP.pde b/java/examples/Books/Nature of Code/chp7_CA/NOC_7_02_GameOfLifeOOP/_7_02_GameOfLifeOOP.pde deleted file mode 100644 index e10b32ef6..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/NOC_7_02_GameOfLifeOOP/_7_02_GameOfLifeOOP.pde +++ /dev/null @@ -1,27 +0,0 @@ -// Daniel Shiffman, Nature of Code -// - -// A basic implementation of John Conway's Game of Life CA - -// Each cell is now an object! - -GOL gol; - -void setup() { - size(400, 400); - smooth(); - gol = new GOL(); -} - -void draw() { - background(255); - - gol.generate(); - gol.display(); -} - -// reset board when mouse is pressed -void mousePressed() { - gol.init(); -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/NOC_7_03_GameOfLifeSimple/GOL.pde b/java/examples/Books/Nature of Code/chp7_CA/NOC_7_03_GameOfLifeSimple/GOL.pde deleted file mode 100644 index 981919ae4..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/NOC_7_03_GameOfLifeSimple/GOL.pde +++ /dev/null @@ -1,73 +0,0 @@ -class GOL { - - int w = 8; - int columns, rows; - - // Game of life board - int[][] board; - - - GOL() { - // Initialize rows, columns and set-up arrays - columns = width/w; - rows = height/w; - board = new int[columns][rows]; - //next = new int[columns][rows]; - // Call function to fill array with random values 0 or 1 - init(); - } - - void init() { - for (int i =1;i < columns-1;i++) { - for (int j =1;j < rows-1;j++) { - board[i][j] = int(random(2)); - } - } - } - - // The process of creating the new generation - void generate() { - - int[][] next = new int[columns][rows]; - - // Loop through every spot in our 2D array and check spots neighbors - for (int x = 1; x < columns-1; x++) { - for (int y = 1; y < rows-1; y++) { - - // Add up all the states in a 3x3 surrounding grid - int neighbors = 0; - for (int i = -1; i <= 1; i++) { - for (int j = -1; j <= 1; j++) { - neighbors += board[x+i][y+j]; - } - } - - // A little trick to subtract the current cell's state since - // we added it in the above loop - neighbors -= board[x][y]; - - // Rules of Life - if ((board[x][y] == 1) && (neighbors < 2)) next[x][y] = 0; // Loneliness - else if ((board[x][y] == 1) && (neighbors > 3)) next[x][y] = 0; // Overpopulation - else if ((board[x][y] == 0) && (neighbors == 3)) next[x][y] = 1; // Reproduction - else next[x][y] = board[x][y]; // Stasis - } - } - - // Next is now our board - board = next; - } - - // This is the easy part, just draw the cells, fill 255 for '1', fill 0 for '0' - void display() { - for ( int i = 0; i < columns;i++) { - for ( int j = 0; j < rows;j++) { - if ((board[i][j] == 1)) fill(0); - else fill(255); - stroke(0); - rect(i*w, j*w, w, w); - } - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp7_CA/NOC_7_03_GameOfLifeSimple/_7_03_GameOfLifeSimple.pde b/java/examples/Books/Nature of Code/chp7_CA/NOC_7_03_GameOfLifeSimple/_7_03_GameOfLifeSimple.pde deleted file mode 100644 index 3ac6009ba..000000000 --- a/java/examples/Books/Nature of Code/chp7_CA/NOC_7_03_GameOfLifeSimple/_7_03_GameOfLifeSimple.pde +++ /dev/null @@ -1,29 +0,0 @@ -// Daniel Shiffman, Nature of Code -// - -// A basic implementation of John Conway's Game of Life CA -// how could this be improved to use object oriented programming? -// think of it as similar to our particle system, with a "cell" class -// to describe each individual cell and a "cellular automata" class -// to describe a collection of cells - -GOL gol; - -void setup() { - size(400, 400); - smooth(); - gol = new GOL(); -} - -void draw() { - background(255); - - gol.generate(); - gol.display(); -} - -// reset board when mouse is pressed -void mousePressed() { - gol.init(); -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/CantorSetArrayList/CantorSetArrayList.pde b/java/examples/Books/Nature of Code/chp8_fractals/CantorSetArrayList/CantorSetArrayList.pde deleted file mode 100644 index 48b2832de..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/CantorSetArrayList/CantorSetArrayList.pde +++ /dev/null @@ -1,47 +0,0 @@ -// Cantor Set -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Renders a simple fractal, the Cantor Set -// Uses an ArrayList to store list of objects -// Generates when mouse is pressed - -float h = 30; - -// List of line objects -ArrayList cantor; - -void setup() { - size(729, 200); - - // Start with one line - cantor = new ArrayList(); - cantor.add(new CantorLine(0, 100, width)); -} - -// Click the mouse to advance the sequence -void mousePressed() { - generate(); -} - -void draw() { - background(255); - // Always show all the lines - for (CantorLine cl : cantor) { - cl.display(); - } - - fill(0); - text("Click mouse to generate",10,height-20); -} - -void generate() { - // Generate the next set of lines - ArrayList next = new ArrayList(); - for (CantorLine cl : cantor) { - next.add(new CantorLine(cl.x,cl.y,cl.len/3)); - next.add(new CantorLine(cl.x+cl.len*2/3,cl.y,cl.len/3)); - } - cantor = next; -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/CantorSetArrayList/Line.pde b/java/examples/Books/Nature of Code/chp8_fractals/CantorSetArrayList/Line.pde deleted file mode 100644 index 7e5c9dffa..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/CantorSetArrayList/Line.pde +++ /dev/null @@ -1,23 +0,0 @@ -// Cantor Set -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Cantor line is a simple horizontal line with a starting point -// and length - -class CantorLine { - float x,y; - float len; - - CantorLine(float x_, float y_, float len_) { - x = x_; - y = y_; - len = len_; - } - - void display() { - stroke(0); - line(x,y,x+len,y); - } - -} diff --git a/java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_01_RecursionLines/Ex_8_01_RecursionLines.pde b/java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_01_RecursionLines/Ex_8_01_RecursionLines.pde deleted file mode 100644 index 0c5f2790f..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_01_RecursionLines/Ex_8_01_RecursionLines.pde +++ /dev/null @@ -1,35 +0,0 @@ -// Simple Recursion -// Daniel Shiffman -// Nature of Code, Chapter 8 - -void setup() { - size(800, 200); - smooth(); -} - -void draw() { - background(255); - drawLines(100,100,700,100); - noLoop(); -} - -void drawLines(float x1, float y1, float x2, float y2) { - - line(x1,y1,x2,y2); - - float dx = x2-x1; - float dy = y2-y1; - - //println(dx + " " + dy); - - if (dx == 0 && dy > 4) { - //println(dy); - drawLines(x1-dy/3,y1,x1+dy/3,y1); - drawLines(x1-dy/3,y2,x1+dy/3,y2); - } else if (dy == 0 && dx > 4) { - //println(dx); - drawLines(x1,y1-dx/3,x1,y1+dx/3); - drawLines(x2,y1-dx/3,x2,y1+dx/3); - } -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_02_KochSnowFlake/Ex_8_02_KochSnowFlake.pde b/java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_02_KochSnowFlake/Ex_8_02_KochSnowFlake.pde deleted file mode 100644 index 8ab63f9c7..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_02_KochSnowFlake/Ex_8_02_KochSnowFlake.pde +++ /dev/null @@ -1,54 +0,0 @@ -// Koch Snowflake -// Daniel Shiffman - -// Renders a simple fractal, the Koch snowflake -// Each recursive level drawn in sequence - -ArrayList lines ; // A list to keep track of all the lines - -void setup() { - size(600, 692); - background(255); - lines = new ArrayList(); - PVector a = new PVector(0, 173); - PVector b = new PVector(width, 173); - PVector c = new PVector(width/2, 173+width*cos(radians(30))); - - // Starting with additional lines - lines.add(new KochLine(a, b)); - lines.add(new KochLine(b, c)); - lines.add(new KochLine(c, a)); - - for (int i = 0; i < 5; i++) { - generate(); - } - - smooth(); -} - -void draw() { - background(255); - for (KochLine l : lines) { - l.display(); - } -} - -void generate() { - ArrayList next = new ArrayList(); // Create emtpy list - for (KochLine l : lines) { - // Calculate 5 koch PVectors (done for us by the line object) - PVector a = l.kochA(); - PVector b = l.kochB(); - PVector c = l.kochC(); - PVector d = l.kochD(); - PVector e = l.kochE(); - // Make line segments between all the PVectors and add them - next.add(new KochLine(a, b)); - next.add(new KochLine(b, c)); - next.add(new KochLine(c, d)); - next.add(new KochLine(d, e)); - } - lines = next; -} - - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_02_KochSnowFlake/KochLine.pde b/java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_02_KochSnowFlake/KochLine.pde deleted file mode 100644 index a241afe1c..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_02_KochSnowFlake/KochLine.pde +++ /dev/null @@ -1,71 +0,0 @@ -// Koch Curve -// Daniel Shiffman - -// A class to describe one line segment in the fractal -// Includes methods to calculate midPVectors along the line according to the Koch algorithm - -class KochLine { - - // Two PVectors, - // a is the "left" PVector and - // b is the "right PVector - PVector start; - PVector end; - - KochLine(PVector a, PVector b) { - start = a.get(); - end = b.get(); - } - - void display() { - stroke(0); - line(start.x, start.y, end.x, end.y); - } - - PVector kochA() { - return start.get(); - } - - - // This is easy, just 1/3 of the way - PVector kochB() { - PVector v = PVector.sub(end, start); - v.div(3); - v.add(start); - return v; - } - - // More complicated, have to use a little trig to figure out where this PVector is! - PVector kochC() { - PVector a = start.get(); // Start at the beginning - - PVector v = PVector.sub(end, start); - v.div(3); - a.add(v); // Move to point B - - rotate(v, -radians(60)); // Rotate 60 degrees - a.add(v); // Move to point C - - return a; - } - - // Easy, just 2/3 of the way - PVector kochD() { - PVector v = PVector.sub(end, start); - v.mult(2/3.0); - v.add(start); - return v; - } - - PVector kochE() { - return end.get(); - } -} - -public void rotate(PVector v, float theta) { - float xTemp = v.x; - // Might need to check for rounding errors like with angleBetween function? - v.x = v.x*PApplet.cos(theta) - v.y*PApplet.sin(theta); - v.y = xTemp*PApplet.sin(theta) + v.y*PApplet.cos(theta); -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_06_Tree/Ex_8_06_Tree.pde b/java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_06_Tree/Ex_8_06_Tree.pde deleted file mode 100644 index 456441db3..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_06_Tree/Ex_8_06_Tree.pde +++ /dev/null @@ -1,56 +0,0 @@ -// Recursive Tree -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Renders a simple tree-like structure via recursion -// Branching angle calculated as a function of horizontal mouse location - -float theta; - -void setup() { - size(1800, 500); - smooth(); -} - -void draw() { - background(255); - // Let's pick an angle 0 to 90 degrees based on the mouse position - theta = PI/6;//map(mouseX,0,width,0,PI/2); - - // Start the tree from the bottom of the screen - translate(width/2, height); - stroke(0); - branch(200,0); - save("chapter08_exc06.png"); - noLoop(); -} - -void branch(float len, int level) { - // Each branch will be 2/3rds the size of the previous one - - //float sw = map(len,2,120,1,10); - //strokeWeight(sw); - strokeWeight(2); - - line(0, 0, 0, -len); - // Move to the end of that line - translate(0, -len); - - len *= 0.66; - level++; - // All recursive functions must have an exit condition!!!! - // Here, ours is when the length of the branch is 2 pixels or less - if (level < 5) { - pushMatrix(); // Save the current state of transformation (i.e. where are we now) - rotate(theta); // Rotate by theta - branch(len,level); // Ok, now call myself to draw two new branches!! - popMatrix(); // Whenever we get back here, we "pop" in order to restore the previous matrix state - - // Repeat the same thing, only branch off to the "left" this time! - pushMatrix(); - rotate(-theta); - branch(len,level); - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_07_Tree/Ex_8_07_Tree.pde b/java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_07_Tree/Ex_8_07_Tree.pde deleted file mode 100644 index 759570bf9..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/Exercise_8_07_Tree/Ex_8_07_Tree.pde +++ /dev/null @@ -1,51 +0,0 @@ -// Recursive Tree -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Renders a simple tree-like structure via recursion -// Branching angle calculated as a function of horizontal mouse location - -float theta; - -void setup() { - size(800, 200); - smooth(); -} - -void draw() { - background(255); - // Let's pick an angle 0 to 90 degrees based on the mouse position - theta = map(mouseX,0,width,0,PI/2); - - // Start the tree from the bottom of the screen - translate(width/2, height); - stroke(0); - branch(60); -} - -void branch(float len) { - // Each branch will be 2/3rds the size of the previous one - float sw = map(len,2,120,1,10); - strokeWeight(sw); - - line(0, 0, 0, -len); - // Move to the end of that line - translate(0, -len); - - len *= 0.66; - // All recursive functions must have an exit condition!!!! - // Here, ours is when the length of the branch is 2 pixels or less - if (len > 2) { - pushMatrix(); // Save the current state of transformation (i.e. where are we now) - rotate(theta); // Rotate by theta - branch(len); // Ok, now call myself to draw two new branches!! - popMatrix(); // Whenever we get back here, we "pop" in order to restore the previous matrix state - - // Repeat the same thing, only branch off to the "left" this time! - pushMatrix(); - rotate(-theta); - branch(len); - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/Figure_8_02_Mandelbrot/Figure_8_02_Mandelbrot.pde b/java/examples/Books/Nature of Code/chp8_fractals/Figure_8_02_Mandelbrot/Figure_8_02_Mandelbrot.pde deleted file mode 100644 index 5de2d26a6..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/Figure_8_02_Mandelbrot/Figure_8_02_Mandelbrot.pde +++ /dev/null @@ -1,79 +0,0 @@ -// The Mandelbrot Set -// Daniel Shiffman - -// Simple rendering of the Mandelbrot set -// c = a + bi -// Iterate z = z^2 + c, i.e. -// z(0) = 0 -// z(1) = 0*0 + c -// z(2) = c*c + c -// z(3) = (c*c + c) * (c*c + c) + c -// etc. - -// c*c = (a+bi) * (a+bi) = a^2 - b^2 + 2abi - -// Created 2 May 2005 - -// Establish a range of values on the complex plane -double xmin = -2.5; double ymin = -1; double w = 4; double h = 2; -// A different range will allow us to "zoom" in or out on the fractal -// double xmin = -1.5; double ymin = -.1; double wh = 0.15; - -void setup() { - size(863,863/2); -} - -void draw() { - - loadPixels(); - - // Maximum number of iterations for each point on the complex plane - int maxiterations = 200; - - // x goes from xmin to xmax - double xmax = xmin + w; - // y goes from ymin to ymax - double ymax = ymin + h; - - // Calculate amount we increment x,y for each pixel - double dx = (xmax - xmin) / (width); - double dy = (ymax - ymin) / (height); - - // Start y - double y = ymin; - for(int j = 0; j < height; j++) { - // Start x - double x = xmin; - for(int i = 0; i < width; i++) { - - // Now we test, as we iterate z = z^2 + cm does z tend towards infinity? - double a = x; - double b = y; - int n = 0; - while (n < maxiterations) { - double aa = a * a; - double bb = b * b; - double twoab = 2.0 * a * b; - a = aa - bb + x; - b = twoab + y; - // Infinty in our finite world is simple, let's just consider it 16 - if(aa + bb > 16.0f) { - break; // Bail - } - n++; - } - - // We color each pixel based on how long it takes to get to infinity - // If we never got there, let's pick the color black - if (n == maxiterations) pixels[i+j*width] = color(0); - else pixels[i+j*width] = color(n*16 % 255); // Gosh, we could make fancy colors here if we wanted - x += dx; - } - y += dy; - } - updatePixels(); - - save("chapter08_02.png"); - noLoop(); -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/Figure_8_14_Koch/Figure_8_14_Koch.pde b/java/examples/Books/Nature of Code/chp8_fractals/Figure_8_14_Koch/Figure_8_14_Koch.pde deleted file mode 100644 index ea0ba890f..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/Figure_8_14_Koch/Figure_8_14_Koch.pde +++ /dev/null @@ -1,65 +0,0 @@ -// Koch Curve -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Renders a simple fractal, the Koch snowflake -// Each recursive level drawn in sequence - -ArrayList lines ; // A list to keep track of all the lines - -void setup() { - size(1820, 200); - - - smooth(); -} - - - -void draw() { - translate(10,0); - int spacing = 10; - int total = 5; - - background(255); - float w = (1800-spacing*(total-1))/5; - for (int n = 0; n < total; n++) { - lines = new ArrayList(); - PVector start = new PVector(0, height*2/3); - PVector end = new PVector(w, height*2/3); - lines.add(new KochLine(start, end)); - for (int i = 0; i < n; i++) { - generate(); - } - strokeWeight(2); - for (KochLine l : lines) { - l.display(); - } - noFill(); - strokeWeight(1); - stroke(127); - rect(0, 10, w,height-20); - translate(w+spacing, 0); - } - save("chapter08_14.png"); - noLoop(); -} - -void generate() { - ArrayList next = new ArrayList(); // Create emtpy list - for (KochLine l : lines) { - // Calculate 5 koch PVectors (done for us by the line object) - PVector a = l.kochA(); - PVector b = l.kochB(); - PVector c = l.kochC(); - PVector d = l.kochD(); - PVector e = l.kochE(); - // Make line segments between all the PVectors and add them - next.add(new KochLine(a, b)); - next.add(new KochLine(b, c)); - next.add(new KochLine(c, d)); - next.add(new KochLine(d, e)); - } - lines = next; -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/Figure_8_14_Koch/KochLine.pde b/java/examples/Books/Nature of Code/chp8_fractals/Figure_8_14_Koch/KochLine.pde deleted file mode 100644 index a241afe1c..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/Figure_8_14_Koch/KochLine.pde +++ /dev/null @@ -1,71 +0,0 @@ -// Koch Curve -// Daniel Shiffman - -// A class to describe one line segment in the fractal -// Includes methods to calculate midPVectors along the line according to the Koch algorithm - -class KochLine { - - // Two PVectors, - // a is the "left" PVector and - // b is the "right PVector - PVector start; - PVector end; - - KochLine(PVector a, PVector b) { - start = a.get(); - end = b.get(); - } - - void display() { - stroke(0); - line(start.x, start.y, end.x, end.y); - } - - PVector kochA() { - return start.get(); - } - - - // This is easy, just 1/3 of the way - PVector kochB() { - PVector v = PVector.sub(end, start); - v.div(3); - v.add(start); - return v; - } - - // More complicated, have to use a little trig to figure out where this PVector is! - PVector kochC() { - PVector a = start.get(); // Start at the beginning - - PVector v = PVector.sub(end, start); - v.div(3); - a.add(v); // Move to point B - - rotate(v, -radians(60)); // Rotate 60 degrees - a.add(v); // Move to point C - - return a; - } - - // Easy, just 2/3 of the way - PVector kochD() { - PVector v = PVector.sub(end, start); - v.mult(2/3.0); - v.add(start); - return v; - } - - PVector kochE() { - return end.get(); - } -} - -public void rotate(PVector v, float theta) { - float xTemp = v.x; - // Might need to check for rounding errors like with angleBetween function? - v.x = v.x*PApplet.cos(theta) - v.y*PApplet.sin(theta); - v.y = xTemp*PApplet.sin(theta) + v.y*PApplet.cos(theta); -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/Figure_8_20_Tree/Figure_8_20_Tree.pde b/java/examples/Books/Nature of Code/chp8_fractals/Figure_8_20_Tree/Figure_8_20_Tree.pde deleted file mode 100644 index b64c609fc..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/Figure_8_20_Tree/Figure_8_20_Tree.pde +++ /dev/null @@ -1,53 +0,0 @@ -// Recursive Tree -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Renders a simple tree-like structure via recursion -// Branching angle calculated as a function of horizontal mouse location - -float theta; - -void setup() { - size(800, 200); - smooth(); -} - -void draw() { - background(255); - // Let's pick an angle 0 to 90 degrees based on the mouse position - theta = map(mouseX,0,width,0,PI/2); - - // Start the tree from the bottom of the screen - translate(width/2, height); - stroke(0); - branch(60); -} - -void branch(float len) { - // Each branch will be 2/3rds the size of the previous one - - //float sw = map(len,2,120,1,10); - //strokeWeight(sw); - strokeWeight(2); - - line(0, 0, 0, -len); - // Move to the end of that line - translate(0, -len); - - len *= 0.66; - // All recursive functions must have an exit condition!!!! - // Here, ours is when the length of the branch is 2 pixels or less - if (len > 2) { - pushMatrix(); // Save the current state of transformation (i.e. where are we now) - rotate(theta); // Rotate by theta - branch(len); // Ok, now call myself to draw two new branches!! - popMatrix(); // Whenever we get back here, we "pop" in order to restore the previous matrix state - - // Repeat the same thing, only branch off to the "left" this time! - pushMatrix(); - rotate(-theta); - branch(len); - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/Figure_8_CantorLine/Figure_8_CantorLine.pde b/java/examples/Books/Nature of Code/chp8_fractals/Figure_8_CantorLine/Figure_8_CantorLine.pde deleted file mode 100644 index c79f11cc4..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/Figure_8_CantorLine/Figure_8_CantorLine.pde +++ /dev/null @@ -1,20 +0,0 @@ - -void setup() { - size(800, 60); - background(255); -} - -void cantor(float x, float y, float len) { - line(x, y, x+len, y); - - y += 20; - line(x,y,x+len/3,y); // [bold] - line(x+len*2/3,y,x+len,y); // [bold] -} - -void draw() { - cantor(10, 20, width-20); - save("chapter08_12.png"); - noLoop(); -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_01_Recursion/_8_01_Recursion.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_01_Recursion/_8_01_Recursion.pde deleted file mode 100644 index 13b5ff2f2..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_01_Recursion/_8_01_Recursion.pde +++ /dev/null @@ -1,26 +0,0 @@ -// Simple Recursion -// Daniel Shiffman -// Nature of Code, Chapter 8 - -void setup() { - size(800,200); - smooth(); -} - -void draw() { - background(255); - drawCircle(width/2,height/2,width); - noLoop(); -} - -// Very simple function that draws one circle -// and recursively calls itself -void drawCircle(int x, int y, float r) { - ellipse(x, y, r, r); - // Exit condition, stop when radius is too small - if(r > 2) { - r *= 0.75f; - // Call the function inside the function! (recursion!) - drawCircle(x, y, r); - } -} diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_02_Recursion/_8_02_Recursion.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_02_Recursion/_8_02_Recursion.pde deleted file mode 100644 index 1a460ecba..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_02_Recursion/_8_02_Recursion.pde +++ /dev/null @@ -1,27 +0,0 @@ -// Simple Recursion -// Daniel Shiffman -// Nature of Code, Chapter 8 - -void setup() { - size(800,200); - smooth(); -} - -void draw() { - background(255); - drawCircle(width/2,height/2,400); - noLoop(); -} - -// Recursive function -void drawCircle(float x, float y, float r) { - stroke(0); - noFill(); - ellipse(x, y, r, r); - if(r > 2) { - // Now we draw two more circles, one to the left - // and one to the right - drawCircle(x + r/2, y, r/2); - drawCircle(x - r/2, y, r/2); - } -} diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_03_KochSimple/KochLine.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_03_KochSimple/KochLine.pde deleted file mode 100644 index a241afe1c..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_03_KochSimple/KochLine.pde +++ /dev/null @@ -1,71 +0,0 @@ -// Koch Curve -// Daniel Shiffman - -// A class to describe one line segment in the fractal -// Includes methods to calculate midPVectors along the line according to the Koch algorithm - -class KochLine { - - // Two PVectors, - // a is the "left" PVector and - // b is the "right PVector - PVector start; - PVector end; - - KochLine(PVector a, PVector b) { - start = a.get(); - end = b.get(); - } - - void display() { - stroke(0); - line(start.x, start.y, end.x, end.y); - } - - PVector kochA() { - return start.get(); - } - - - // This is easy, just 1/3 of the way - PVector kochB() { - PVector v = PVector.sub(end, start); - v.div(3); - v.add(start); - return v; - } - - // More complicated, have to use a little trig to figure out where this PVector is! - PVector kochC() { - PVector a = start.get(); // Start at the beginning - - PVector v = PVector.sub(end, start); - v.div(3); - a.add(v); // Move to point B - - rotate(v, -radians(60)); // Rotate 60 degrees - a.add(v); // Move to point C - - return a; - } - - // Easy, just 2/3 of the way - PVector kochD() { - PVector v = PVector.sub(end, start); - v.mult(2/3.0); - v.add(start); - return v; - } - - PVector kochE() { - return end.get(); - } -} - -public void rotate(PVector v, float theta) { - float xTemp = v.x; - // Might need to check for rounding errors like with angleBetween function? - v.x = v.x*PApplet.cos(theta) - v.y*PApplet.sin(theta); - v.y = xTemp*PApplet.sin(theta) + v.y*PApplet.cos(theta); -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_03_KochSimple/_8_03_KochSimple.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_03_KochSimple/_8_03_KochSimple.pde deleted file mode 100644 index 0bfb84f6c..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_03_KochSimple/_8_03_KochSimple.pde +++ /dev/null @@ -1,50 +0,0 @@ - // Koch Curve -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Renders a simple fractal, the Koch snowflake -// Each recursive level drawn in sequence - -ArrayList lines ; // A list to keep track of all the lines - -void setup() { - size(600, 300); - background(255); - lines = new ArrayList(); - PVector start = new PVector(0, 200); - PVector end = new PVector(width, 200); - lines.add(new KochLine(start, end)); - - for (int i = 0; i < 5; i++) { - generate(); - } - - smooth(); -} - -void draw() { - background(255); - for (KochLine l : lines) { - l.display(); - } -} - -void generate() { - ArrayList next = new ArrayList(); // Create emtpy list - for (KochLine l : lines) { - // Calculate 5 koch PVectors (done for us by the line object) - PVector a = l.kochA(); - PVector b = l.kochB(); - PVector c = l.kochC(); - PVector d = l.kochD(); - PVector e = l.kochE(); - // Make line segments between all the PVectors and add them - next.add(new KochLine(a, b)); - next.add(new KochLine(b, c)); - next.add(new KochLine(c, d)); - next.add(new KochLine(d, e)); - } - lines = next; -} - - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_03_Recursion/_8_03_Recursion.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_03_Recursion/_8_03_Recursion.pde deleted file mode 100644 index 55672e39f..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_03_Recursion/_8_03_Recursion.pde +++ /dev/null @@ -1,28 +0,0 @@ -// Simple Recursion -// Daniel Shiffman -// Nature of Code, Chapter 8 - -void setup() { - size(800, 200); - smooth(); -} - -void draw() { - background(255); - drawCircle(width/2, height/2, 400); - noLoop(); -} - -void drawCircle(float x, float y, float radius) { - noFill(); - stroke(0); - ellipse(x, y, radius, radius); - if (radius > 8) { - // Four circles! left right, up and down - drawCircle(x + radius/2, y, radius/2); - drawCircle(x - radius/2, y, radius/2); - drawCircle(x, y + radius/2, radius/2); - drawCircle(x, y - radius/2, radius/2); - } -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_04_CantorSet/_8_04_CantorSet.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_04_CantorSet/_8_04_CantorSet.pde deleted file mode 100644 index 8bced0afb..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_04_CantorSet/_8_04_CantorSet.pde +++ /dev/null @@ -1,38 +0,0 @@ -// Cantor Set -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Renders a simple fractal, the Cantor Set - -void setup() { - size(800, 200); - background(255); - - // Call the recursive function - cantor(35, 0, 730); -} - -void draw() { - // No need to loop - noLoop(); -} - - -void cantor(float x, float y, float len) { - - float h = 30; - - // recursive exit condition - if (len >= 1) { - // Draw line (as rectangle to make it easier to see) - noStroke(); - fill(0); - rect(x, y, len, h/3); - // Go down to next y position - y += h; - // Draw 2 more lines 1/3rd the length (without the middle section) - cantor(x, y, len/3); - cantor(x+len*2/3, y, len/3); - } -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_04_Tree/_8_04_Tree.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_04_Tree/_8_04_Tree.pde deleted file mode 100644 index 2cf4d38da..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_04_Tree/_8_04_Tree.pde +++ /dev/null @@ -1,52 +0,0 @@ -// Recursive Tree -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Renders a simple tree-like structure via recursion -// Branching angle calculated as a function of horizontal mouse location - -float theta; - -void setup() { - size(300, 200); - smooth(); -} - -void draw() { - background(255); - // Let's pick an angle 0 to 90 degrees based on the mouse position - theta = map(mouseX,0,width,0,PI/2); - - // Start the tree from the bottom of the screen - translate(width/2, height); - stroke(0); - branch(60); -} - -void branch(float len) { - // Each branch will be 2/3rds the size of the previous one - - float sw = map(len,2,120,1,10); - strokeWeight(sw); - - line(0, 0, 0, -len); - // Move to the end of that line - translate(0, -len); - - len *= 0.66; - // All recursive functions must have an exit condition!!!! - // Here, ours is when the length of the branch is 2 pixels or less - if (len > 2) { - pushMatrix(); // Save the current state of transformation (i.e. where are we now) - rotate(theta); // Rotate by theta - branch(len); // Ok, now call myself to draw two new branches!! - popMatrix(); // Whenever we get back here, we "pop" in order to restore the previous matrix state - - // Repeat the same thing, only branch off to the "left" this time! - pushMatrix(); - rotate(-theta); - branch(len); - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/KochFractal.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/KochFractal.pde deleted file mode 100644 index c045cdd9d..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/KochFractal.pde +++ /dev/null @@ -1,70 +0,0 @@ -// Koch Curve -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// A class to manage the list of line segments in the snowflake pattern - -class KochFractal { - PVector start; // A PVector for the start - PVector end; // A PVector for the end - ArrayList lines; // A list to keep track of all the lines - int count; - - public KochFractal() { - start = new PVector(0,height-20); - end = new PVector(width,height-20); - lines = new ArrayList(); - restart(); - } - - void nextLevel() { - // For every line that is in the arraylist - // create 4 more lines in a new arraylist - lines = iterate(lines); - count++; - } - - void restart() { - count = 0; // Reset count - lines.clear(); // Empty the array list - lines.add(new KochLine(start,end)); // Add the initial line (from one end PVector to the other) - } - - int getCount() { - return count; - } - - // This is easy, just draw all the lines - void render() { - for(KochLine l : lines) { - l.display(); - } - } - - // This is where the **MAGIC** happens - // Step 1: Create an empty arraylist - // Step 2: For every line currently in the arraylist - // - calculate 4 line segments based on Koch algorithm - // - add all 4 line segments into the new arraylist - // Step 3: Return the new arraylist and it becomes the list of line segments for the structure - - // As we do this over and over again, each line gets broken into 4 lines, which gets broken into 4 lines, and so on. . . - ArrayList iterate(ArrayList before) { - ArrayList now = new ArrayList(); // Create emtpy list - for(KochLine l : before) { - // Calculate 5 koch PVectors (done for us by the line object) - PVector a = l.start(); - PVector b = l.kochleft(); - PVector c = l.kochmiddle(); - PVector d = l.kochright(); - PVector e = l.end(); - // Make line segments between all the PVectors and add them - now.add(new KochLine(a,b)); - now.add(new KochLine(b,c)); - now.add(new KochLine(c,d)); - now.add(new KochLine(d,e)); - } - return now; - } - -} diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/KochLine.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/KochLine.pde deleted file mode 100644 index 9f4f59871..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/KochLine.pde +++ /dev/null @@ -1,73 +0,0 @@ -// Koch Curve -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// A class to describe one line segment in the fractal -// Includes methods to calculate midPVectors along the line according to the Koch algorithm - -class KochLine { - - // Two PVectors, - // a is the "left" PVector and - // b is the "right PVector - PVector a; - PVector b; - - KochLine(PVector start, PVector end) { - a = start.get(); - b = end.get(); - } - - void display() { - stroke(0); - line(a.x, a.y, b.x, b.y); - } - - PVector start() { - return a.get(); - } - - PVector end() { - return b.get(); - } - - // This is easy, just 1/3 of the way - PVector kochleft() { - PVector v = PVector.sub(b, a); - v.div(3); - v.add(a); - return v; - } - - // More complicated, have to use a little trig to figure out where this PVector is! - PVector kochmiddle() { - PVector v = PVector.sub(b, a); - v.div(3); - - PVector p = a.get(); - p.add(v); - - rotate(v,-radians(60)); - p.add(v); - - return p; - } - - - // Easy, just 2/3 of the way - PVector kochright() { - PVector v = PVector.sub(a, b); - v.div(3); - v.add(b); - return v; - } -} - - public void rotate(PVector v, float theta) { - float xTemp = v.x; - // Might need to check for rounding errors like with angleBetween function? - v.x = v.x*cos(theta) - v.y*sin(theta); - v.y = xTemp*sin(theta) + v.y*cos(theta); - } - - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/_8_05_Koch.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/_8_05_Koch.pde deleted file mode 100644 index 8d6fe3a35..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/_8_05_Koch.pde +++ /dev/null @@ -1,29 +0,0 @@ -// Koch Curve -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Renders a simple fractal, the Koch snowflake -// Each recursive level drawn in sequence - -KochFractal k; - -void setup() { - size(800,250); - background(255); - frameRate(1); // Animate slowly - k = new KochFractal(); - smooth(); -} - -void draw() { - background(255); - // Draws the snowflake! - k.render(); - // Iterate - k.nextLevel(); - // Let's not do it more than 5 times. . . - if (k.getCount() > 5) { - k.restart(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/sketch.properties b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/sketch.properties deleted file mode 100644 index 140966b6e..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/sketch.properties +++ /dev/null @@ -1,2 +0,0 @@ -mode.id=processing.mode.javascript.JavaScriptMode -mode=JavaScript diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/web-export/_8_05_Koch.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/web-export/_8_05_Koch.pde deleted file mode 100644 index 178fae466..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/web-export/_8_05_Koch.pde +++ /dev/null @@ -1,174 +0,0 @@ -// Koch Curve -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Renders a simple fractal, the Koch snowflake -// Each recursive level drawn in sequence - -KochFractal k; - -void setup() { - size(800,250); - background(255); - //frameRate(1); // Animate slowly - k = new KochFractal(); - smooth(); -} - -void draw() { - background(255); - // Draws the snowflake! - k.render(); - // Iterate - k.nextLevel(); - // Let's not do it more than 5 times. . . - if (k.getCount() > 5) { - k.restart(); - } - println(frameCount); -} - -// Koch Curve -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// A class to manage the list of line segments in the snowflake pattern - -class KochFractal { - PVector start; // A PVector for the start - PVector end; // A PVector for the end - ArrayList lines; // A list to keep track of all the lines - int count; - - public KochFractal() { - start = new PVector(0,height-20); - end = new PVector(width,height-20); - lines = new ArrayList(); - restart(); - } - - void nextLevel() { - // For every line that is in the arraylist - // create 4 more lines in a new arraylist - lines = iterate(lines); - count++; - } - - void restart() { - count = 0; // Reset count - lines.clear(); // Empty the array list - lines.add(new KochLine(start,end)); // Add the initial line (from one end PVector to the other) - } - - int getCount() { - return count; - } - - // This is easy, just draw all the lines - void render() { - for(KochLine l : lines) { - l.display(); - } - } - - // This is where the **MAGIC** happens - // Step 1: Create an empty arraylist - // Step 2: For every line currently in the arraylist - // - calculate 4 line segments based on Koch algorithm - // - add all 4 line segments into the new arraylist - // Step 3: Return the new arraylist and it becomes the list of line segments for the structure - - // As we do this over and over again, each line gets broken into 4 lines, which gets broken into 4 lines, and so on. . . - ArrayList iterate(ArrayList before) { - ArrayList now = new ArrayList(); // Create emtpy list - for(KochLine l : before) { - // Calculate 5 koch PVectors (done for us by the line object) - PVector a = l.start(); - PVector b = l.kochleft(); - PVector c = l.kochmiddle(); - PVector d = l.kochright(); - PVector e = l.end(); - // Make line segments between all the PVectors and add them - now.add(new KochLine(a,b)); - now.add(new KochLine(b,c)); - now.add(new KochLine(c,d)); - now.add(new KochLine(d,e)); - } - return now; - } - -} -// Koch Curve -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// A class to describe one line segment in the fractal -// Includes methods to calculate midPVectors along the line according to the Koch algorithm - -class KochLine { - - // Two PVectors, - // a is the "left" PVector and - // b is the "right PVector - PVector a; - PVector b; - - KochLine(PVector start, PVector end) { - a = start.get(); - b = end.get(); - } - - void display() { - stroke(0); - line(a.x, a.y, b.x, b.y); - } - - PVector start() { - return a.get(); - } - - PVector end() { - return b.get(); - } - - // This is easy, just 1/3 of the way - PVector kochleft() { - PVector v = PVector.sub(b, a); - v.div(3); - v.add(a); - return v; - } - - // More complicated, have to use a little trig to figure out where this PVector is! - PVector kochmiddle() { - PVector v = PVector.sub(b, a); - v.div(3); - - PVector p = a.get(); - p.add(v); - - rotate(v,-radians(60)); - p.add(v); - - return p; - } - - - // Easy, just 2/3 of the way - PVector kochright() { - PVector v = PVector.sub(a, b); - v.div(3); - v.add(b); - return v; - } -} - - public void rotate(PVector v, float theta) { - float xTemp = v.x; - // Might need to check for rounding errors like with angleBetween function? - v.x = v.x*cos(theta) - v.y*sin(theta); - v.y = xTemp*sin(theta) + v.y*cos(theta); - } - - - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/web-export/processing.js b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/web-export/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_Koch/web-export/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_KochSimple/KochLine.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_KochSimple/KochLine.pde deleted file mode 100644 index a241afe1c..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_KochSimple/KochLine.pde +++ /dev/null @@ -1,71 +0,0 @@ -// Koch Curve -// Daniel Shiffman - -// A class to describe one line segment in the fractal -// Includes methods to calculate midPVectors along the line according to the Koch algorithm - -class KochLine { - - // Two PVectors, - // a is the "left" PVector and - // b is the "right PVector - PVector start; - PVector end; - - KochLine(PVector a, PVector b) { - start = a.get(); - end = b.get(); - } - - void display() { - stroke(0); - line(start.x, start.y, end.x, end.y); - } - - PVector kochA() { - return start.get(); - } - - - // This is easy, just 1/3 of the way - PVector kochB() { - PVector v = PVector.sub(end, start); - v.div(3); - v.add(start); - return v; - } - - // More complicated, have to use a little trig to figure out where this PVector is! - PVector kochC() { - PVector a = start.get(); // Start at the beginning - - PVector v = PVector.sub(end, start); - v.div(3); - a.add(v); // Move to point B - - rotate(v, -radians(60)); // Rotate 60 degrees - a.add(v); // Move to point C - - return a; - } - - // Easy, just 2/3 of the way - PVector kochD() { - PVector v = PVector.sub(end, start); - v.mult(2/3.0); - v.add(start); - return v; - } - - PVector kochE() { - return end.get(); - } -} - -public void rotate(PVector v, float theta) { - float xTemp = v.x; - // Might need to check for rounding errors like with angleBetween function? - v.x = v.x*PApplet.cos(theta) - v.y*PApplet.sin(theta); - v.y = xTemp*PApplet.sin(theta) + v.y*PApplet.cos(theta); -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_KochSimple/_8_05_KochSimple.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_KochSimple/_8_05_KochSimple.pde deleted file mode 100644 index e387ed5c4..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_KochSimple/_8_05_KochSimple.pde +++ /dev/null @@ -1,50 +0,0 @@ - // Koch Curve -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Renders a simple fractal, the Koch snowflake -// Each recursive level drawn in sequence - -ArrayList lines ; // A list to keep track of all the lines - -void setup() { - size(383, 200); - background(255); - lines = new ArrayList(); - PVector start = new PVector(0, 150); - PVector end = new PVector(width, 150); - lines.add(new KochLine(start, end)); - - for (int i = 0; i < 5; i++) { - generate(); - } - - smooth(); -} - -void draw() { - background(255); - for (KochLine l : lines) { - l.display(); - } -} - -void generate() { - ArrayList next = new ArrayList(); // Create emtpy list - for (KochLine l : lines) { - // Calculate 5 koch PVectors (done for us by the line object) - PVector a = l.kochA(); - PVector b = l.kochB(); - PVector c = l.kochC(); - PVector d = l.kochD(); - PVector e = l.kochE(); - // Make line segments between all the PVectors and add them - next.add(new KochLine(a, b)); - next.add(new KochLine(b, c)); - next.add(new KochLine(c, d)); - next.add(new KochLine(d, e)); - } - lines = next; -} - - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_TreeStochastic/_8_05_TreeStochastic.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_TreeStochastic/_8_05_TreeStochastic.pde deleted file mode 100644 index 17acd3e21..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_05_TreeStochastic/_8_05_TreeStochastic.pde +++ /dev/null @@ -1,63 +0,0 @@ -// Stochastic Tree -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Renders a simple tree-like structure via recursion -// Angles and number of branches are random - -void setup() { - size(600, 400); - smooth(); - newTree(); -} - -void draw() { - -} - -void mousePressed() { - newTree(); -} - -void newTree() { - background(255); - fill(0); - text("Click mouse to generate a new tree", 10, height-20); - - stroke(0); - // Start the tree from the bottom of the screen - translate(width/2, height); - // Start the recursive branching! - branch(120); -} - - - -void branch(float h) { - // thickness of the branch is mapped to its length - float sw = map(h, 2, 120, 1, 5); - strokeWeight(sw); - // Draw the actual branch - line(0, 0, 0, -h); - // Move along to end - translate(0, -h); - - // Each branch will be 2/3rds the size of the previous one - h *= 0.66f; - - // All recursive functions must have an exit condition!!!! - // Here, ours is when the length of the branch is 2 pixels or less - if (h > 2) { - // A random number of branches - int n = int(random(1, 4)); - for (int i = 0; i < n; i++) { - // Picking a random angle - float theta = random(-PI/2, PI/2); - pushMatrix(); // Save the current state of transformation (i.e. where are we now) - rotate(theta); // Rotate by theta - branch(h); // Ok, now call myself to branch again - popMatrix(); // Whenever we get back here, we "pop" in order to restore the previous matrix state - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_06_SimpleLSystem/_8_06_SimpleLSystem.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_06_SimpleLSystem/_8_06_SimpleLSystem.pde deleted file mode 100644 index 14e10da7e..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_06_SimpleLSystem/_8_06_SimpleLSystem.pde +++ /dev/null @@ -1,47 +0,0 @@ -// L-System -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Just demonstrating working with L-System strings -// No drawing - -// Start with "A" -String current = "A"; -// Number of generations -int count = 0; - -void setup() { - size(200, 200); - println("Generation " + count + ": " + current); -} - -void draw() { - background(255); - fill(0); - text("Click mouse to generate", 10, height-20); - noLoop(); -} - -void mousePressed() { - // A new StringBuffer for the next generation - StringBuffer next = new StringBuffer(); - - // Look through the current String to replace according to L-System rules - for (int i = 0; i < current.length(); i++) { - char c = current.charAt(i); - if (c == 'A') { - // If we find A replace with AB - next.append("AB"); - } else if (c == 'B') { - // If we find B replace with A - next.append("A"); - } - } - // The current String is now the next one - current = next.toString(); - count++; - // Print to message console - println("Generation " + count + ": " + current); - println(count + " " + current.length()); -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_06_Tree/_8_06_Tree.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_06_Tree/_8_06_Tree.pde deleted file mode 100644 index 4b415662d..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_06_Tree/_8_06_Tree.pde +++ /dev/null @@ -1,53 +0,0 @@ -// Recursive Tree -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Renders a simple tree-like structure via recursion -// Branching angle calculated as a function of horizontal mouse location - -float theta; - -void setup() { - size(250, 200); - smooth(); -} - -void draw() { - background(255); - // Let's pick an angle 0 to 90 degrees based on the mouse position - theta = map(mouseX,0,width,0,PI/2); - - // Start the tree from the bottom of the screen - translate(width/2, height); - stroke(0); - branch(60); -} - -void branch(float len) { - // Each branch will be 2/3rds the size of the previous one - - //float sw = map(len,2,120,1,10); - //strokeWeight(sw); - strokeWeight(2); - - line(0, 0, 0, -len); - // Move to the end of that line - translate(0, -len); - - len *= 0.66; - // All recursive functions must have an exit condition!!!! - // Here, ours is when the length of the branch is 2 pixels or less - if (len > 2) { - pushMatrix(); // Save the current state of transformation (i.e. where are we now) - rotate(theta); // Rotate by theta - branch(len); // Ok, now call myself to draw two new branches!! - popMatrix(); // Whenever we get back here, we "pop" in order to restore the previous matrix state - - // Repeat the same thing, only branch off to the "left" this time! - pushMatrix(); - rotate(-theta); - branch(len); - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_06_Tree_static/_8_06_Tree_static.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_06_Tree_static/_8_06_Tree_static.pde deleted file mode 100644 index 92805fdb4..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_06_Tree_static/_8_06_Tree_static.pde +++ /dev/null @@ -1,45 +0,0 @@ -// Recursive Tree -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Renders a simple tree-like structure via recursion -// Branching angle calculated as a function of horizontal mouse location - -void setup() { - size(800, 200); - smooth(); -} - -void draw() { - background(255); - // Start the tree from the bottom of the screen - translate(width/2, height); - stroke(0); - branch(60); - noLoop(); -} - -void branch(float len) { - strokeWeight(2); - - line(0, 0, 0, -len); - // Move to the end of that line - translate(0, -len); - - len *= 0.66; - // All recursive functions must have an exit condition!!!! - // Here, ours is when the length of the branch is 2 pixels or less - if (len > 2) { - pushMatrix(); // Save the current state of transformation (i.e. where are we now) - rotate(PI/5); // Rotate by theta - branch(len); // Ok, now call myself to draw two new branches!! - popMatrix(); // Whenever we get back here, we "pop" in order to restore the previous matrix state - - // Repeat the same thing, only branch off to the "left" this time! - pushMatrix(); - rotate(-PI/5); - branch(len); - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_07_TreeStochastic/_8_07_TreeStochastic.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_07_TreeStochastic/_8_07_TreeStochastic.pde deleted file mode 100644 index 9b6af0bc7..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_07_TreeStochastic/_8_07_TreeStochastic.pde +++ /dev/null @@ -1,66 +0,0 @@ -// Stochastic Tree -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Renders a simple tree-like structure via recursion -// Angles and number of branches are random - -void setup() { - size(800, 200); - smooth(); - newTree(); -} - -void draw() { - noLoop(); -} - -void mousePressed() { - newTree(); - redraw(); -} - -void newTree() { - background(255); - fill(0); - text("Click mouse to generate a new tree", 10, height-10); - - stroke(0); - pushMatrix(); - // Start the tree from the bottom of the screen - translate(width/2, height); - // Start the recursive branching! - branch(80); - popMatrix(); -} - - - -void branch(float h) { - // thickness of the branch is mapped to its length - float sw = map(h, 2, 120, 1, 5); - strokeWeight(sw); - // Draw the actual branch - line(0, 0, 0, -h); - // Move along to end - translate(0, -h); - - // Each branch will be 2/3rds the size of the previous one - h *= 0.66f; - - // All recursive functions must have an exit condition!!!! - // Here, ours is when the length of the branch is 2 pixels or less - if (h > 2) { - // A random number of branches - int n = int(random(1, 4)); - for (int i = 0; i < n; i++) { - // Picking a random angle - float theta = random(-PI/2, PI/2); - pushMatrix(); // Save the current state of transformation (i.e. where are we now) - rotate(theta); // Rotate by theta - branch(h); // Ok, now call myself to branch again - popMatrix(); // Whenever we get back here, we "pop" in order to restore the previous matrix state - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_07_TreeStochastic_angleonly/_8_07_TreeStochastic_angleonly.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_07_TreeStochastic_angleonly/_8_07_TreeStochastic_angleonly.pde deleted file mode 100644 index ef4b2a41b..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_07_TreeStochastic_angleonly/_8_07_TreeStochastic_angleonly.pde +++ /dev/null @@ -1,59 +0,0 @@ -// Stochastic Tree -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Renders a simple tree-like structure via recursion -// Angles and number of branches are random - -void setup() { - size(800, 200); - smooth(); - newTree(); -} - -void draw() { - noLoop(); -} - -void mousePressed() { - pushMatrix(); - newTree(); - popMatrix(); - redraw(); -} - -void newTree() { - background(255); - fill(0); - text("Click mouse to generate a new tree", 10, height-10); - - stroke(0); - // Start the tree from the bottom of the screen - translate(width/2, height); - // Start the recursive branching! - branch(60); -} - - - -void branch(float h) { - // thickness of the branch is mapped to its length - float sw = map(h, 2, 120, 1, 5); - strokeWeight(sw); - float theta = random(0,PI/3); - - line(0, 0, 0, -h); - translate(0, -h); - h *= 0.66; - if (h > 2) { - pushMatrix(); - rotate(theta); - branch(h); - popMatrix(); - pushMatrix(); - rotate(-theta); - branch(h); - popMatrix(); - } -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_08_SimpleLSystem/_8_08_SimpleLSystem.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_08_SimpleLSystem/_8_08_SimpleLSystem.pde deleted file mode 100644 index da65cab34..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_08_SimpleLSystem/_8_08_SimpleLSystem.pde +++ /dev/null @@ -1,47 +0,0 @@ -// L-System -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Just demonstrating working with L-System strings -// No drawing - -// Start with "A" -String current = "A"; -// Number of generations -int count = 0; - -void setup() { - size(800, 200); - println("Generation " + count + ": " + current); -} - -void draw() { - background(255); - fill(0); - text("Click mouse to generate", 10, height-20); - noLoop(); -} - -void mousePressed() { - // A new StringBuffer for the next generation - StringBuffer next = new StringBuffer(); - - // Look through the current String to replace according to L-System rules - for (int i = 0; i < current.length(); i++) { - char c = current.charAt(i); - if (c == 'A') { - // If we find A replace with AB - next.append("AB"); - } else if (c == 'B') { - // If we find B replace with A - next.append("A"); - } - } - // The current String is now the next one - current = next.toString(); - count++; - // Print to message console - println("Generation " + count + ": " + current); - //println(count + " " + current.length()); -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/LSystem.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/LSystem.pde deleted file mode 100644 index 3d381bd82..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/LSystem.pde +++ /dev/null @@ -1,67 +0,0 @@ -/* Daniel Shiffman */ -/* Programming from A to Z */ -/* Spring 2006 */ -/* http://www.shiffman.net */ -/* daniel.shiffman@nyu.edu */ - -/* LSystem Class */ - -// An LSystem has a starting sentence -// An a ruleset -// Each generation recursively replaces characteres in the sentence -// Based on the rulset - -class LSystem { - - String sentence; // The sentence (a String) - Rule[] ruleset; // The ruleset (an array of Rule objects) - int generation; // Keeping track of the generation # - - // Construct an LSystem with a startin sentence and a ruleset - LSystem(String axiom, Rule[] r) { - sentence = axiom; - ruleset = r; - generation = 0; - } - - // Generate the next generation - void generate() { - // An empty StringBuffer that we will fill - StringBuffer nextgen = new StringBuffer(); - // For every character in the sentence - for (int i = 0; i < sentence.length(); i++) { - // What is the character - char curr = sentence.charAt(i); - // We will replace it with itself unless it matches one of our rules - String replace = "" + curr; - // Check every rule - for (int j = 0; j < ruleset.length; j++) { - char a = ruleset[j].getA(); - // if we match the Rule, get the replacement String out of the Rule - if (a == curr) { - replace = ruleset[j].getB(); - break; - } - } - // Append replacement String - nextgen.append(replace); - } - // Replace sentence - sentence = nextgen.toString(); - // Increment generation - generation++; - } - - String getSentence() { - return sentence; - } - - int getGeneration() { - return generation; - } - - -} - - - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/Rule.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/Rule.pde deleted file mode 100644 index 43142063e..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/Rule.pde +++ /dev/null @@ -1,26 +0,0 @@ -/* Daniel Shiffman */ -/* http://www.shiffman.net */ - -/* A Class to describe an - LSystem Rule */ - -class Rule { - char a; - String b; - - Rule(char a_, String b_) { - a = a_; - b = b_; - } - - char getA() { - return a; - } - - String getB() { - return b; - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/Turtle.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/Turtle.pde deleted file mode 100644 index 0193562e2..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/Turtle.pde +++ /dev/null @@ -1,53 +0,0 @@ -/* Daniel Shiffman */ -/* http://www.shiffman.net */ - -class Turtle { - - String todo; - float len; - float theta; - - Turtle(String s, float l, float t) { - todo = s; - len = l; - theta = t; - } - - void render() { - stroke(0,175); - for (int i = 0; i < todo.length(); i++) { - char c = todo.charAt(i); - if (c == 'F' || c == 'G') { - line(0,0,len,0); - translate(len,0); - } - else if (c == '+') { - rotate(theta); - } - else if (c == '-') { - rotate(-theta); - } - else if (c == '[') { - pushMatrix(); - } - else if (c == ']') { - popMatrix(); - } - } - } - - void setLen(float l) { - len = l; - } - - void changeLen(float percent) { - len *= percent; - } - - void setToDo(String s) { - todo = s; - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/_8_09_LSystem.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/_8_09_LSystem.pde deleted file mode 100644 index 9d745a120..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/_8_09_LSystem.pde +++ /dev/null @@ -1,63 +0,0 @@ -/* Daniel Shiffman */ -/* The Nature of Code */ -/* http://www.shiffman.net */ -/* daniel.shiffman@nyu.edu */ - -LSystem lsys; -Turtle turtle; - -void setup() { - size(800, 200); - /* - // Create an empty ruleset - Rule[] ruleset = new Rule[2]; - // Fill with two rules (These are rules for the Sierpinksi Gasket Triangle) - ruleset[0] = new Rule('F',"F--F--F--G"); - ruleset[1] = new Rule('G',"GG"); - // Create LSystem with axiom and ruleset - lsys = new LSystem("F--F--F",ruleset); - turtle = new Turtle(lsys.getSentence(),width*2,TWO_PI/3); - */ - - /*Rule[] ruleset = new Rule[1]; - //ruleset[0] = new Rule('F',"F[F]-F+F[--F]+F-F"); - ruleset[0] = new Rule['F',"FF+[+F-F-F]-[-F+F+F]"); - lsys = new LSystem("F-F-F-F",ruleset); - turtle = new Turtle(lsys.getSentence(),width-1,PI/2); - */ - - Rule[] ruleset = new Rule[1]; - ruleset[0] = new Rule('F', "FF+[+F-F-F]-[-F+F+F]"); - lsys = new LSystem("F", ruleset); - turtle = new Turtle(lsys.getSentence(), height/3, radians(25)); - - - - smooth(); -} - -void draw() { - background(255); - fill(0); - //text("Click mouse to generate", 10, height-10); - - translate(width/2, height); - rotate(-PI/2); - turtle.render(); - noLoop(); -} - -int counter = 0; - -void mousePressed() { - if (counter < 5) { - pushMatrix(); - lsys.generate(); - turtle.setToDo(lsys.getSentence()); - turtle.changeLen(0.5); - popMatrix(); - redraw(); - counter++; - } -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/sketch.properties b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/sketch.properties deleted file mode 100644 index b3cbe600e..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/sketch.properties +++ /dev/null @@ -1,2 +0,0 @@ -mode.id=processing.mode.java.JavaMode -mode=Standard diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/web-export/_8_09_LSystem.pde b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/web-export/_8_09_LSystem.pde deleted file mode 100644 index ee477e204..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/web-export/_8_09_LSystem.pde +++ /dev/null @@ -1,210 +0,0 @@ -/* Daniel Shiffman */ -/* The Nature of Code */ -/* http://www.shiffman.net */ -/* daniel.shiffman@nyu.edu */ - -LSystem lsys; -Turtle turtle; - -void setup() { - size(800, 200); - /* - // Create an empty ruleset - Rule[] ruleset = new Rule[2]; - // Fill with two rules (These are rules for the Sierpinksi Gasket Triangle) - ruleset[0] = new Rule('F',"F--F--F--G"); - ruleset[1] = new Rule('G',"GG"); - // Create LSystem with axiom and ruleset - lsys = new LSystem("F--F--F",ruleset); - turtle = new Turtle(lsys.getSentence(),width*2,TWO_PI/3); - */ - - /*Rule[] ruleset = new Rule[1]; - //ruleset[0] = new Rule('F',"F[F]-F+F[--F]+F-F"); - ruleset[0] = new Rule['F',"FF+[+F-F-F]-[-F+F+F]"); - lsys = new LSystem("F-F-F-F",ruleset); - turtle = new Turtle(lsys.getSentence(),width-1,PI/2); - */ - - Rule[] ruleset = new Rule[1]; - ruleset[0] = new Rule('F', "FF+[+F-F-F]-[-F+F+F]"); - lsys = new LSystem("F", ruleset); - turtle = new Turtle(lsys.getSentence(), height/3, radians(25)); - - - - smooth(); -} - -void draw() { - background(255); - fill(0); - //text("Click mouse to generate", 10, height-10); - - translate(width/2, height); - rotate(-PI/2); - turtle.render(); - noLoop(); -} - -int counter = 0; - -void mousePressed() { - if (counter < 5) { - pushMatrix(); - lsys.generate(); - turtle.setToDo(lsys.getSentence()); - turtle.changeLen(0.5); - popMatrix(); - redraw(); - counter++; - } -} - -/* Daniel Shiffman */ -/* Programming from A to Z */ -/* Spring 2006 */ -/* http://www.shiffman.net */ -/* daniel.shiffman@nyu.edu */ - -/* LSystem Class */ - -// An LSystem has a starting sentence -// An a ruleset -// Each generation recursively replaces characteres in the sentence -// Based on the rulset - -class LSystem { - - String sentence; // The sentence (a String) - Rule[] ruleset; // The ruleset (an array of Rule objects) - int generation; // Keeping track of the generation # - - // Construct an LSystem with a startin sentence and a ruleset - LSystem(String axiom, Rule[] r) { - sentence = axiom; - ruleset = r; - generation = 0; - } - - // Generate the next generation - void generate() { - // An empty StringBuffer that we will fill - StringBuffer nextgen = new StringBuffer(); - // For every character in the sentence - for (int i = 0; i < sentence.length(); i++) { - // What is the character - char curr = sentence.charAt(i); - // We will replace it with itself unless it matches one of our rules - String replace = "" + curr; - // Check every rule - for (int j = 0; j < ruleset.length; j++) { - char a = ruleset[j].getA(); - // if we match the Rule, get the replacement String out of the Rule - if (a == curr) { - replace = ruleset[j].getB(); - break; - } - } - // Append replacement String - nextgen.append(replace); - } - // Replace sentence - sentence = nextgen.toString(); - // Increment generation - generation++; - } - - String getSentence() { - return sentence; - } - - int getGeneration() { - return generation; - } - - -} - - - -/* Daniel Shiffman */ -/* http://www.shiffman.net */ - -/* A Class to describe an - LSystem Rule */ - -class Rule { - char a; - String b; - - Rule(char a_, String b_) { - a = a_; - b = b_; - } - - char getA() { - return a; - } - - String getB() { - return b; - } - -} - - -/* Daniel Shiffman */ -/* http://www.shiffman.net */ - -class Turtle { - - String todo; - float len; - float theta; - - Turtle(String s, float l, float t) { - todo = s; - len = l; - theta = t; - } - - void render() { - stroke(0,175); - for (int i = 0; i < todo.length(); i++) { - char c = todo.charAt(i); - if (c == 'F' || c == 'G') { - line(0,0,len,0); - translate(len,0); - } - else if (c == '+') { - rotate(theta); - } - else if (c == '-') { - rotate(-theta); - } - else if (c == '[') { - pushMatrix(); - } - else if (c == ']') { - popMatrix(); - } - } - } - - void setLen(float l) { - len = l; - } - - void changeLen(float percent) { - len *= percent; - } - - void setToDo(String s) { - todo = s; - } - -} - - - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/web-export/processing.js b/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/web-export/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/NOC_8_09_LSystem/web-export/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/Tree2/Branch.pde b/java/examples/Books/Nature of Code/chp8_fractals/Tree2/Branch.pde deleted file mode 100644 index 67f073dcf..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/Tree2/Branch.pde +++ /dev/null @@ -1,59 +0,0 @@ -// Recursive Tree (w/ ArrayList) -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// A class for one branch in the system - -class Branch { - // Each has a location, velocity, and timer - // We could implement this same idea with different data - PVector loc; - PVector vel; - float timer; - float timerstart; - - Branch(PVector l, PVector v, float n) { - loc = l.get(); - vel = v.get(); - timerstart = n; - timer = timerstart; - } - - // Move location - void update() { - loc.add(vel); - } - - // Draw a dot at location - void render() { - fill(0); - noStroke(); - ellipseMode(CENTER); - ellipse(loc.x,loc.y,2,2); - } - - // Did the timer run out? - boolean timeToBranch() { - timer--; - if (timer < 0) { - return true; - } else { - return false; - } - } - - // Create a new branch at the current location, but change direction by a given angle - Branch branch(float angle) { - // What is my current heading - float theta = vel.heading2D(); - // What is my current speed - float mag = vel.mag(); - // Turn me - theta += radians(angle); - // Look, polar coordinates to cartesian!! - PVector newvel = new PVector(mag*cos(theta),mag*sin(theta)); - // Return a new Branch - return new Branch(loc,newvel,timerstart*0.66f); - } - -} diff --git a/java/examples/Books/Nature of Code/chp8_fractals/Tree2/Tree2.pde b/java/examples/Books/Nature of Code/chp8_fractals/Tree2/Tree2.pde deleted file mode 100644 index 3d558d0d9..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/Tree2/Tree2.pde +++ /dev/null @@ -1,47 +0,0 @@ -// Recursive Tree (w/ ArrayList) -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Recursive branching "structure" without an explicitly recursive function -// Instead we have an ArrayList to hold onto N number of elements -// For every element in the ArrayList, we add 2 more elements, etc. (this is the recursion) - -// An arraylist that will keep track of all current branches -ArrayList tree; - -void setup() { - size(200,200); - background(255); - smooth(); - - // Setup the arraylist and add one branch to it - tree = new ArrayList(); - // A branch has a starting location, a starting "velocity", and a starting "timer" - Branch b = new Branch(new PVector(width/2,height),new PVector(0,-0.5),100); - // Add to arraylist - tree.add(b); -} - -void draw() { - // Try erasing the background to see how it works - // background(255); - - // Let's stop when the arraylist gets too big - if (tree.size() < 1024) { - // For every branch in the arraylist - for (int i = tree.size()-1; i >= 0; i--) { - // Get the branch, update and draw it - Branch b = tree.get(i); - b.update(); - b.render(); - // If it's ready to split - if (b.timeToBranch()) { - tree.remove(i); // Delete it - tree.add(b.branch( 30)); // Add one going right - tree.add(b.branch(-25)); // Add one going left - } - } - } -} - - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/Tree3/Branch.pde b/java/examples/Books/Nature of Code/chp8_fractals/Tree3/Branch.pde deleted file mode 100644 index a6921813b..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/Tree3/Branch.pde +++ /dev/null @@ -1,66 +0,0 @@ -// Recursive Tree (w/ ArrayList) -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// A class for one branch in the system - -class Branch { - // Each has a location, velocity, and timer - // We could implement this same idea with different data - PVector start; - PVector end; - PVector vel; - float timer; - float timerstart; - - boolean growing = true; - - Branch(PVector l, PVector v, float n) { - start = l.get(); - end = l.get(); - vel = v.get(); - timerstart = n; - timer = timerstart; - } - - // Move location - void update() { - if (growing) { - end.add(vel); - } - } - - // Draw a dot at location - void render() { - stroke(0); - line(start.x,start.y,end.x,end.y); - } - - // Did the timer run out? - boolean timeToBranch() { - timer--; - if (timer < 0 && growing) { - growing = false; - return true; - } - else { - return false; - } - } - - // Create a new branch at the current location, but change direction by a given angle - Branch branch(float angle) { - // What is my current heading - float theta = vel.heading2D(); - // What is my current speed - float mag = vel.mag(); - // Turn me - theta += radians(angle); - // Look, polar coordinates to cartesian!! - PVector newvel = new PVector(mag*cos(theta),mag*sin(theta)); - // Return a new Branch - return new Branch(end,newvel,timerstart*0.66f); - } - -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/Tree3/Leaf.pde b/java/examples/Books/Nature of Code/chp8_fractals/Tree3/Leaf.pde deleted file mode 100644 index 145e0d1ce..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/Tree3/Leaf.pde +++ /dev/null @@ -1,21 +0,0 @@ -// Recursive Tree (w/ ArrayList) -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// A class for a leaf that gets placed at the end of -// the last branches - -class Leaf { - PVector loc; - - Leaf(PVector l) { - loc = l.get(); - } - - void display() { - noStroke(); - fill(50,100); - ellipse(loc.x,loc.y,4,4); - } -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/Tree3/Tree3.pde b/java/examples/Books/Nature of Code/chp8_fractals/Tree3/Tree3.pde deleted file mode 100644 index 612650d72..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/Tree3/Tree3.pde +++ /dev/null @@ -1,58 +0,0 @@ -// Recursive Tree (w/ ArrayList) -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Recursive branching "structure" without an explicitly recursive function -// Instead we have an ArrayList to hold onto N number of elements -// For every element in the ArrayList, we add 2 more elements, etc. (this is the recursion) - -// An arraylist that will keep track of all current branches -ArrayList tree; -ArrayList leaves; - -void setup() { - size(200,200); - background(255); - smooth(); - - // Setup the arraylist and add one branch to it - tree = new ArrayList(); - leaves = new ArrayList(); - // A branch has a starting location, a starting "velocity", and a starting "timer" - Branch b = new Branch(new PVector(width/2,height),new PVector(0,-0.5),100); - // Add to arraylist - tree.add(b); -} - -void draw() { - background(255); - - // Let's stop when the arraylist gets too big - // For every branch in the arraylist - for (int i = tree.size()-1; i >= 0; i--) { - // Get the branch, update and draw it - Branch b = tree.get(i); - b.update(); - b.render(); - // If it's ready to split - if (b.timeToBranch()) { - if (tree.size() < 1024) { - //tree.remove(i); // Delete it - tree.add(b.branch( 30)); // Add one going right - tree.add(b.branch(-25)); // Add one going left - } - else { - leaves.add(new Leaf(b.end)); - } - } - } - - for (Leaf leaf : leaves) { - leaf.display(); - } - -} - - - - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/TreeStochasticNoise/TreeStochasticNoise.pde b/java/examples/Books/Nature of Code/chp8_fractals/TreeStochasticNoise/TreeStochasticNoise.pde deleted file mode 100644 index 2a5544943..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/TreeStochasticNoise/TreeStochasticNoise.pde +++ /dev/null @@ -1,71 +0,0 @@ -// Stochastic Tree with angles fluctuating with Perlin noise -// Daniel Shiffman -// Nature of Code, Chapter 8 - -// Perlin noise offset -float yoff = 0; -// Random seed to control randomness while drawing the tree -int seed = 5; - - -void setup() { - size(800, 200); - smooth(); -} - -void draw() { - background(255); - fill(0); - //text("Click mouse to generate a new tree", 10, height-20); - - stroke(0); - // Start the tree from the bottom of the screen - translate(width/2, height); - // Move alogn through noise - yoff += 0.005; - randomSeed(seed); - // Start the recursive branching! - branch(60, 0); -} - - -void mousePressed() { - // New tree starts with new noise offset and new random seed - yoff = random(1000); - seed = millis(); -} - - -void branch(float h, float xoff) { - // thickness of the branch is mapped to its length - float sw = map(h, 2, 100, 1, 5); - strokeWeight(sw); - // Draw the branch - line(0, 0, 0, -h); - // Move along to end - translate(0, -h); - - // Each branch will be 2/3rds the size of the previous one - h *= 0.7f; - - // Move along through noise space - xoff += 0.1; - - if (h > 4) { - // Random number of branches - int n = int(random(0, 5)); - for (int i = 0; i < n; i++) { - - // Here the angle is controlled by perlin noise - // This is a totally arbitrary way to do it, try others! - float theta = map(noise(xoff+i, yoff), 0, 1, -PI/3, PI/3); - if (n%2==0) theta *= -1; - - pushMatrix(); // Save the current state of transformation (i.e. where are we now) - rotate(theta); // Rotate by theta - branch(h, xoff); // Ok, now call myself to branch again - popMatrix(); // Whenever we get back here, we "pop" in order to restore the previous matrix state - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/TreeStochasticNoise/sketch.properties b/java/examples/Books/Nature of Code/chp8_fractals/TreeStochasticNoise/sketch.properties deleted file mode 100644 index 28faa5897..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/TreeStochasticNoise/sketch.properties +++ /dev/null @@ -1 +0,0 @@ -mode=Standard diff --git a/java/examples/Books/Nature of Code/chp8_fractals/lsys/LSystem.pde b/java/examples/Books/Nature of Code/chp8_fractals/lsys/LSystem.pde deleted file mode 100644 index 3d381bd82..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/lsys/LSystem.pde +++ /dev/null @@ -1,67 +0,0 @@ -/* Daniel Shiffman */ -/* Programming from A to Z */ -/* Spring 2006 */ -/* http://www.shiffman.net */ -/* daniel.shiffman@nyu.edu */ - -/* LSystem Class */ - -// An LSystem has a starting sentence -// An a ruleset -// Each generation recursively replaces characteres in the sentence -// Based on the rulset - -class LSystem { - - String sentence; // The sentence (a String) - Rule[] ruleset; // The ruleset (an array of Rule objects) - int generation; // Keeping track of the generation # - - // Construct an LSystem with a startin sentence and a ruleset - LSystem(String axiom, Rule[] r) { - sentence = axiom; - ruleset = r; - generation = 0; - } - - // Generate the next generation - void generate() { - // An empty StringBuffer that we will fill - StringBuffer nextgen = new StringBuffer(); - // For every character in the sentence - for (int i = 0; i < sentence.length(); i++) { - // What is the character - char curr = sentence.charAt(i); - // We will replace it with itself unless it matches one of our rules - String replace = "" + curr; - // Check every rule - for (int j = 0; j < ruleset.length; j++) { - char a = ruleset[j].getA(); - // if we match the Rule, get the replacement String out of the Rule - if (a == curr) { - replace = ruleset[j].getB(); - break; - } - } - // Append replacement String - nextgen.append(replace); - } - // Replace sentence - sentence = nextgen.toString(); - // Increment generation - generation++; - } - - String getSentence() { - return sentence; - } - - int getGeneration() { - return generation; - } - - -} - - - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/lsys/Rule.pde b/java/examples/Books/Nature of Code/chp8_fractals/lsys/Rule.pde deleted file mode 100644 index 43142063e..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/lsys/Rule.pde +++ /dev/null @@ -1,26 +0,0 @@ -/* Daniel Shiffman */ -/* http://www.shiffman.net */ - -/* A Class to describe an - LSystem Rule */ - -class Rule { - char a; - String b; - - Rule(char a_, String b_) { - a = a_; - b = b_; - } - - char getA() { - return a; - } - - String getB() { - return b; - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/lsys/Turtle.pde b/java/examples/Books/Nature of Code/chp8_fractals/lsys/Turtle.pde deleted file mode 100644 index ac0ffa8d9..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/lsys/Turtle.pde +++ /dev/null @@ -1,53 +0,0 @@ -/* Daniel Shiffman */ -/* http://www.shiffman.net */ - -class Turtle { - - String todo; - float len; - float theta; - - Turtle(String s, float l, float t) { - todo = s; - len = l; - theta = t; - } - - void render() { - stroke(0); - for (int i = 0; i < todo.length(); i++) { - char c = todo.charAt(i); - if (c == 'F' || c == 'G') { - line(0,0,len,0); - translate(len,0); - } - else if (c == '+') { - rotate(theta); - } - else if (c == '-') { - rotate(-theta); - } - else if (c == '[') { - pushMatrix(); - } - else if (c == ']') { - popMatrix(); - } - } - } - - void setLen(float l) { - len = l; - } - - void changeLen(float percent) { - len *= percent; - } - - void setToDo(String s) { - todo = s; - } - -} - - diff --git a/java/examples/Books/Nature of Code/chp8_fractals/lsys/lsys.pde b/java/examples/Books/Nature of Code/chp8_fractals/lsys/lsys.pde deleted file mode 100644 index 8ed2d08bd..000000000 --- a/java/examples/Books/Nature of Code/chp8_fractals/lsys/lsys.pde +++ /dev/null @@ -1,56 +0,0 @@ -/* Daniel Shiffman */ -/* The Nature of Code */ -/* http://www.shiffman.net */ -/* daniel.shiffman@nyu.edu */ - -LSystem lsys; -Turtle turtle; - -void setup() { - size(600, 600); - /* - // Create an empty ruleset - Rule[] ruleset = new Rule[2]; - // Fill with two rules (These are rules for the Sierpinksi Gasket Triangle) - ruleset[0] = new Rule('F',"F--F--F--G"); - ruleset[1] = new Rule('G',"GG"); - // Create LSystem with axiom and ruleset - lsys = new LSystem("F--F--F",ruleset); - turtle = new Turtle(lsys.getSentence(),width*2,TWO_PI/3); - */ - - /*Rule[] ruleset = new Rule[1]; - //ruleset[0] = new Rule('F',"F[F]-F+F[--F]+F-F"); - ruleset[0] = new Rule['F',"FF+[+F-F-F]-[-F+F+F]"); - lsys = new LSystem("F-F-F-F",ruleset); - turtle = new Turtle(lsys.getSentence(),width-1,PI/2); - */ - - Rule[] ruleset = new Rule[1]; - ruleset[0] = new Rule('F', "FF+[+F-F-F]-[-F+F+F]"); - lsys = new LSystem("F", ruleset); - turtle = new Turtle(lsys.getSentence(), width/4, radians(25)); - - - - smooth(); -} - -void draw() { - background(255); - fill(0); - text("Click mouse to generate", 10, height-20); - - translate(width/2, height); - rotate(-PI/2); - turtle.render(); - noLoop(); -} - -void mousePressed() { - lsys.generate(); - turtle.setToDo(lsys.getSentence()); - turtle.changeLen(0.5); - redraw(); -} - diff --git a/java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/DNA.pde b/java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/DNA.pde deleted file mode 100644 index 9e7ce4bc8..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/DNA.pde +++ /dev/null @@ -1,51 +0,0 @@ -// Pathfinding w/ Genetic Algorithms -// Daniel Shiffman - -// DNA is an array of vectors - -class DNA { - - // The genetic sequence - PVector[] genes; - - // Constructor (makes a DNA of random PVectors) - DNA(int num) { - genes = new PVector[num]; - for (int i = 0; i < genes.length; i++) { - float angle = random(TWO_PI); - genes[i] = new PVector(cos(angle),sin(angle)); - } - } - - // Constructor #2, creates the instance based on an existing array - DNA(PVector[] newgenes) { - // We could make a copy if necessary - // genes = (PVector []) newgenes.clone(); - genes = newgenes; - } - - // CROSSOVER - // Creates new DNA sequence from two (this & and a partner) - DNA crossover(DNA partner) { - PVector[] child = new PVector[genes.length]; - // Pick a midpoint - int crossover = int(random(genes.length)); - // Take "half" from one and "half" from the other - for (int i = 0; i < genes.length; i++) { - if (i > crossover) child[i] = genes[i]; - else child[i] = partner.genes[i]; - } - DNA newgenes = new DNA(child); - return newgenes; - } - - // Based on a mutation probability, picks a new random Vector - void mutate(float m) { - for (int i = 0; i < genes.length; i++) { - if (random(1) < m) { - float angle = random(TWO_PI); - genes[i] = new PVector(cos(angle),sin(angle)); - } - } - } -} diff --git a/java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/EvolveFlowField.pde b/java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/EvolveFlowField.pde deleted file mode 100644 index ce43c9f67..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/EvolveFlowField.pde +++ /dev/null @@ -1,100 +0,0 @@ -// Pathfinding Flowfield w/ Genetic Algorithms -// Daniel Shiffman - -// This example produces an obstacle course with a start and finish -// Virtual "creatures" are rewarded for making it closer to the finish - -// Each creature's DNA is a "flowfield" of PVectors that -// determine steering vectors for each cell on the screen - -int gridscale = 24; // Scale of grid is 1/24 of screen size - -// DNA needs one vector for every spot on the grid -// (it's like a pixel array, but with vectors instead of colors) -int dnasize; - -int lifetime; // How long should each generation live - -// Global maxforce and maxspeed (hmmm, could make this part of DNA??) -float maxspeed = 4.0; -float maxforce = 1.0; - -Population population; // Population -int lifecycle; // Timer for cycle of generation -int recordtime; // Fastest time to target -Obstacle target; // Target location -Obstacle start; // Start location -int diam = 24; // Size of target - -ArrayList obstacles; //an array list to keep track of all the obstacles! - -void setup() { - size(640,480); - smooth(); - - dnasize = (width / gridscale) * (height / gridscale); - lifetime = width/2; - - // Initialize variables - lifecycle = 0; - recordtime = lifetime; - target = new Obstacle(width-diam-diam/2,height/2-diam/2,diam,diam); - start = new Obstacle(diam/2,height/2-diam/2,diam,diam); - - // Create a population with a mutation rate, and population max - int popmax = 1000; - float mutationRate = 0.05; - population = new Population(mutationRate,popmax); - - // Create the obstacle course - obstacles = new ArrayList(); - obstacles.add(new Obstacle(width/4,40,10,height-80)); - obstacles.add(new Obstacle(width/2,0,10,height/2-10)); - obstacles.add(new Obstacle(width/2,height-height/2+10,10,height/2-10)); - obstacles.add(new Obstacle(2*width/3,height/2-height/8,10,height/4)); -} - -void draw() { - background(255); - - // Draw the start and target locations - start.display(); - target.display(); - - // Draw the obstacles - for (Obstacle obs : obstacles) { - obs.display(); - } - - - // If the generation hasn't ended yet - if (lifecycle < lifetime) { - population.live(obstacles); - if ((population.targetReached()) && (lifecycle < recordtime)) { - recordtime = lifecycle; - } - lifecycle++; - // Otherwise a new generation - } else { - lifecycle = 0; - population.calcFitness(); - population.naturalSelection(); - population.generate(); - } - - // Display some info - textAlign(RIGHT); - fill(0); - text("Generation #:" + population.getGenerations(),width-10,18); - text("Cycles left:" + ((lifetime-lifecycle)/10),width-10,36); - text("Record cycles: " + recordtime,width-10,54); - -} - -// Move the target if the mouse is pressed -// System will adapt to new target -void mousePressed() { - target = new Obstacle(mouseX,mouseY,diam,diam); - recordtime = lifetime; -} - diff --git a/java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/Obstacle.pde b/java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/Obstacle.pde deleted file mode 100644 index 250edc4cd..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/Obstacle.pde +++ /dev/null @@ -1,34 +0,0 @@ -// Pathfinding w/ Genetic Algorithms -// Daniel Shiffman - -// A class for an obstacle, just a simple rectangle that is drawn -// and can check if a creature touches it - -// Also using this class for starting point and target location - -import java.awt.Rectangle; - -class Obstacle { - - Rectangle r; - - Obstacle(int x, int y, int w, int h) { - r = new Rectangle(x,y,w,h); - } - - void display() { - stroke(0); - fill(175); - rectMode(CORNER); - rect(r.x,r.y,r.width,r.height); - } - - boolean contains(PVector spot) { - if (r.contains((int)spot.x,(int)spot.y)) { - return true; - } else { - return false; - } - } - -} diff --git a/java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/Population.pde b/java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/Population.pde deleted file mode 100644 index a5b283ea6..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/Population.pde +++ /dev/null @@ -1,115 +0,0 @@ -// Pathfinding w/ Genetic Algorithms -// Daniel Shiffman - -// A class to describe a population of "creatures" - -class Population { - - float mutationRate; // Mutation rate - Rocket[] population; // Array to hold the current population - ArrayList darwin; // ArrayList which we will use for our "mating pool" - int generations; // Number of generations - - int order; // Keep track of the order of creature's finishing the maze - - // Initialize the population - Population(float m, int num) { - mutationRate = m; - population = new Rocket[num]; - darwin = new ArrayList(); - generations = 0; - //make a new set of creatures - for (int i = 0; i < population.length; i++) { - PVector location = new PVector(start.r.x+start.r.width/2,start.r.y+start.r.height/2); - population[i] = new Rocket(location, new DNA(dnasize)); - } - order = 1; // The first one to finish will be #1 - } - - void live (ArrayList o) { - // For every creature - for (int i = 0; i < population.length; i++) { - // If it finishes, mark it down as done! - if ((population[i].finished()) && (!population[i].stopped())) { - population[i].setFinish(order); - order++; - } - // Run it - population[i].run(o); - } - } - - // Did anything finish? - boolean targetReached() { - for (int i = 0; i < population.length; i++) { - if (population[i].finished()) return true; - } - return false; - } - - // Calculate fitness for each creature - void calcFitness() { - for (int i = 0; i < population.length; i++) { - population[i].calcFitness(); - } - order = 1; // Hmmm, awkward place for this, we have to reset this for the next generation - } - - // Generate a mating pool - void naturalSelection() { - // Clear the ArrayList - darwin.clear(); - - // Calculate total fitness of whole population - float totalFitness = getTotalFitness(); - - // Calculate normalized fitness for each member of the population - // Based on normalized fitness, each member will get added to the mating pool a certain number of times a la roulette wheel - // A higher fitness = more entries to mating pool = more likely to be picked as a parent - // A lower fitness = fewer entries to mating pool = less likely to be picked as a parent - for (int i = 0; i < population.length; i++) { - float fitnessNormal = population[i].getFitness() / totalFitness; - int n = (int) (fitnessNormal * 50000); // Arbitrary multiplier, consider mapping fix - for (int j = 0; j < n; j++) { - darwin.add(population[i]); - } - } - } - - // Making the next generation - void generate() { - // Refill the population with children from the mating pool - for (int i = 0; i < population.length; i++) { - int m = int(random(darwin.size())); - int d = int(random(darwin.size())); - // Pick two parents - Rocket mom = darwin.get(m); - Rocket dad = darwin.get(d); - // Get their genes - DNA momgenes = mom.getDNA(); - DNA dadgenes = dad.getDNA(); - // Mate their genes - DNA child = momgenes.crossover(dadgenes); - // Mutate their genes - child.mutate(mutationRate); - // Fill the new population with the new child - PVector location = new PVector(start.r.x+start.r.width/2,start.r.y+start.r.height/2); - population[i] = new Rocket(location, child); - } - generations++; - } - - int getGenerations() { - return generations; - } - - //compute total fitness for the population - float getTotalFitness() { - float total = 0; - for (int i = 0; i < population.length; i++) { - total += population[i].getFitness(); - } - return total; - } - -} diff --git a/java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/Rocket.pde b/java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/Rocket.pde deleted file mode 100644 index 1327ee928..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/EvolveFlowField/Rocket.pde +++ /dev/null @@ -1,149 +0,0 @@ -// Pathfinding w/ Genetic Algorithms -// Daniel Shiffman - -// Rocket class -- this is just like our Boid / Particle class -// the only difference is that it has DNA & fitness - -class Rocket { - - // All of our physics stuff - PVector location; - PVector velocity; - PVector acceleration; - float r; - float recordDist; - - float fitness; - DNA dna; - - boolean stopped; // Am I stuck? - int finish; // What was my finish? (first, second, etc. . . ) - - //constructor - Rocket(PVector l, DNA dna_) { - acceleration = new PVector(); - velocity = new PVector(); - location = l.get(); - r = 2; - dna = dna_; - stopped = false; - finish = 100000; // Some high number to begin with - recordDist = width; - } - - // FITNESS FUNCTION - // distance = distance from target - // finish = what order did i finish (first, second, etc. . .) - // f(distance,finish) = (1.0f / finish^1.5) * (1.0f / distance^6); - // a lower finish is rewarded (exponentially) and/or shorter distance to target (exponetially) - void calcFitness() { - float d = recordDist; - if (d < diam/2) { - d = 1.0; - } - // Reward finishing faster and getting closer - fitness = (1.0f / pow(finish,1.5)) * (1 / (pow(d,6))); - } - - void setFinish(int f) { - finish = f; - } - - // Run in relation to all the obstacles - // If I'm stuck, don't bother updating or checking for intersection - void run(ArrayList o) { - if (!stopped) { - update(); - // If I hit an edge or an obstacle - if ((borders()) || (obstacles(o))) { - stopped = true; - } - } - // Draw me! - display(); - } - - // Did I hit an edge? - boolean borders() { - if ((location.x < 0) || (location.y < 0) || (location.x > width) || (location.y > height)) { - return true; - } else { - return false; - } - } - - // Did I make it to the target? - boolean finished() { - float d = dist(location.x,location.y,target.r.x,target.r.y); - if (d < recordDist) recordDist = d; - if (target.contains(location)) { - stopped = true; - return true; - } - return false; - } - - // Did I hit an obstacle? - boolean obstacles(ArrayList o) { - for (Obstacle obs : o) { - if (obs.contains(location)) { - return true; - } - } - return false; - } - - void update() { - if (!finished()) { - // Where are we? Our location will tell us what steering vector to look up in our DNA; - int x = (int) location.x/gridscale; - int y = (int) location.y/gridscale; - x = constrain(x,0,width/gridscale-1); // Make sure we are not off the edge - y = constrain(y,0,height/gridscale-1); // Make sure we are not off the edge - - // Get the steering vector out of our genes in the right spot - // We could do (desired - velocity) to be more in line with the Reynolds flow field following - acceleration.add(dna.genes[x+y*width/gridscale]); - - // This is all the same stuff we've done before - acceleration.mult(maxforce); - velocity.add(acceleration); - velocity.limit(maxspeed); - location.add(velocity); - acceleration.mult(0); - } - } - - void display() { - //fill(0,150); - //stroke(0); - //ellipse(location.x,location.y,r,r); - float theta = velocity.heading2D() + PI/2; - fill(200,100); - stroke(0); - pushMatrix(); - translate(location.x,location.y); - rotate(theta); - beginShape(TRIANGLES); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(); - popMatrix(); - - - } - - float getFitness() { - return fitness; - } - - DNA getDNA() { - return dna; - } - - boolean stopped() { - return stopped; - } - -} diff --git a/java/examples/Books/Nature of Code/chp9_ga/GA_Shakespeare_fancyfitness/DNA.pde b/java/examples/Books/Nature of Code/chp9_ga/GA_Shakespeare_fancyfitness/DNA.pde deleted file mode 100644 index 516c3f98d..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/GA_Shakespeare_fancyfitness/DNA.pde +++ /dev/null @@ -1,67 +0,0 @@ -// Genetic Algorithm, Evolving Shakespeare -// Daniel Shiffman - -// A class to describe a psuedo-DNA, i.e. genotype -// Here, a virtual organism's DNA is an array of character. -// Functionality: -// -- convert DNA into a string -// -- calculate DNA's "fitness" -// -- mate DNA with another set of DNA -// -- mutate DNA - - -class DNA { - - // The genetic sequence - char[] genes; - - float fitness; - - // Constructor (makes a random DNA) - DNA(int num) { - genes = new char[num]; - for (int i = 0; i < genes.length; i++) { - genes[i] = (char) random(32,128); // Pick from range of chars - } - } - - // Converts character array to a String - String getPhrase() { - return new String(genes); - } - - // Fitness function (returns floating point % of "correct" characters) - void fitness (String target) { - int score = 0; - for (int i = 0; i < genes.length; i++) { - if (genes[i] == target.charAt(i)) { - score++; - } - } - fitness = pow(2,score); - } - - // Crossover - DNA crossover(DNA partner) { - // A new child - DNA child = new DNA(genes.length); - - int midpoint = int(random(genes.length)); // Pick a midpoint - - // Half from one, half from the other - for (int i = 0; i < genes.length; i++) { - if (i > midpoint) child.genes[i] = genes[i]; - else child.genes[i] = partner.genes[i]; - } - return child; - } - - // Based on a mutation probability, picks a new random character - void mutate(float mutationRate) { - for (int i = 0; i < genes.length; i++) { - if (random(1) < mutationRate) { - genes[i] = (char) random(32,128); - } - } - } -} diff --git a/java/examples/Books/Nature of Code/chp9_ga/GA_Shakespeare_fancyfitness/GA_Shakespeare_fancyfitness.pde b/java/examples/Books/Nature of Code/chp9_ga/GA_Shakespeare_fancyfitness/GA_Shakespeare_fancyfitness.pde deleted file mode 100644 index b739fa570..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/GA_Shakespeare_fancyfitness/GA_Shakespeare_fancyfitness.pde +++ /dev/null @@ -1,86 +0,0 @@ -// Genetic Algorithm, Evolving Shakespeare -// Daniel Shiffman - -// Demonstration of using a genetic algorithm to perform a search - -// setup() -// # Step 1: The populationation -// # Create an empty populationation (an array or ArrayList) -// # Fill it with DNA encoded objects (pick random values to start) - -// draw() -// # Step 1: Selection -// # Create an empty mating pool (an empty ArrayList) -// # For every member of the populationation, evaluate its fitness based on some criteria / function, -// and add it to the mating pool in a manner consistant with its fitness, i.e. the more fit it -// is the more times it appears in the mating pool, in order to be more likely picked for reproduction. - -// # Step 2: Reproduction Create a new empty populationation -// # Fill the new populationation by executing the following steps: -// 1. Pick two "parent" objects from the mating pool. -// 2. Crossover -- create a "child" object by mating these two parents. -// 3. Mutation -- mutate the child's DNA based on a given probability. -// 4. Add the child object to the new populationation. -// # Replace the old populationation with the new populationation -// -// # Rinse and repeat - - -PFont f; -String target; -int popmax; -float mutationRate; -Population population; - -void setup() { - size(600, 200); - f = createFont("Courier", 32, true); - target = "To be or not to be."; - popmax = 150; - mutationRate = 0.01; - - // Create a populationation with a target phrase, mutation rate, and populationation max - population = new Population(target, mutationRate, popmax); -} - -void draw() { - // Generate mating pool - population.naturalSelection(); - //Create next generation - population.generate(); - // Calculate fitness - population.calcFitness(); - displayInfo(); - - // If we found the target phrase, stop - if (population.finished()) { - println(millis()/1000.0); - noLoop(); - } -} - -void displayInfo() { - background(255); - // Display current status of populationation - String answer = population.getBest(); - textFont(f); - textAlign(LEFT); - fill(0); - - - textSize(16); - text("Best phrase:",20,30); - textSize(32); - text(answer, 20, 75); - - textSize(12); - text("total generations: " + population.getGenerations(), 20, 140); - text("average fitness: " + nf(population.getAverageFitness(), 0, 2), 20, 155); - text("total populationation: " + popmax, 20, 170); - text("mutation rate: " + int(mutationRate * 100) + "%", 20, 185); - - textSize(10); - text("All phrases:\n" + population.allPhrases(), 450, 10); -} - - diff --git a/java/examples/Books/Nature of Code/chp9_ga/GA_Shakespeare_fancyfitness/Population.pde b/java/examples/Books/Nature of Code/chp9_ga/GA_Shakespeare_fancyfitness/Population.pde deleted file mode 100644 index e8dbe67cd..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/GA_Shakespeare_fancyfitness/Population.pde +++ /dev/null @@ -1,127 +0,0 @@ -// Genetic Algorithm, Evolving Shakespeare -// Daniel Shiffman - -// A class to describe a population of virtual organisms -// In this case, each organism is just an instance of a DNA object - - - - -class Population { - - float mutationRate; // Mutation rate - DNA[] population; // Array to hold the current population - ArrayList matingPool; // ArrayList which we will use for our "mating pool" - String target; // Target phrase - int generations; // Number of generations - boolean finished; // Are we finished evolving? -int perfectScore; - - Population(String p, float m, int num) { - target = p; - mutationRate = m; - population = new DNA[num]; - for (int i = 0; i < population.length; i++) { - population[i] = new DNA(target.length()); - } - calcFitness(); - matingPool = new ArrayList(); - finished = false; - generations = 0; - - perfectScore = int(pow(2,target.length())); - } - - // Fill our fitness array with a value for every member of the population - void calcFitness() { - for (int i = 0; i < population.length; i++) { - population[i].fitness(target); - } - } - - // Generate a mating pool - void naturalSelection() { - // Clear the ArrayList - matingPool.clear(); - - float maxFitness = 0; - for (int i = 0; i < population.length; i++) { - if (population[i].fitness > maxFitness) { - maxFitness = population[i].fitness; - } - } - - // Based on fitness, each member will get added to the mating pool a certain number of times - // a higher fitness = more entries to mating pool = more likely to be picked as a parent - // a lower fitness = fewer entries to mating pool = less likely to be picked as a parent - for (int i = 0; i < population.length; i++) { - - float fitness = map(population[i].fitness,0,maxFitness,0,1); - int n = int(fitness * 100); // Arbitrary multiplier, we can also use monte carlo method - for (int j = 0; j < n; j++) { // and pick two random numbers - matingPool.add(population[i]); - } - } - } - - // Create a new generation - void generate() { - // Refill the population with children from the mating pool - for (int i = 0; i < population.length; i++) { - int a = int(random(matingPool.size())); - int b = int(random(matingPool.size())); - DNA partnerA = matingPool.get(a); - DNA partnerB = matingPool.get(b); - DNA child = partnerA.crossover(partnerB); - child.mutate(mutationRate); - population[i] = child; - } - generations++; - } - - - // Compute the current "most fit" member of the population - String getBest() { - float worldrecord = 0.0f; - int index = 0; - for (int i = 0; i < population.length; i++) { - if (population[i].fitness > worldrecord) { - index = i; - worldrecord = population[i].fitness; - } - } - - if (worldrecord == perfectScore ) finished = true; - return population[index].getPhrase(); - } - - boolean finished() { - return finished; - } - - int getGenerations() { - return generations; - } - - // Compute average fitness for the population - float getAverageFitness() { - float total = 0; - for (int i = 0; i < population.length; i++) { - total += population[i].fitness; - } - return total / (population.length); - } - - String allPhrases() { - String everything = ""; - - int displayLimit = min(population.length,50); - - - for (int i = 0; i < displayLimit; i++) { - everything += population[i].getPhrase() + "\n"; - } - return everything; - } -} - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/DNA.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/DNA.pde deleted file mode 100644 index dd3e31563..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/DNA.pde +++ /dev/null @@ -1,67 +0,0 @@ -// Genetic Algorithm, Evolving Shakespeare -// Daniel Shiffman - -// A class to describe a psuedo-DNA, i.e. genotype -// Here, a virtual organism's DNA is an array of character. -// Functionality: -// -- convert DNA into a string -// -- calculate DNA's "fitness" -// -- mate DNA with another set of DNA -// -- mutate DNA - - -class DNA { - - // The genetic sequence - char[] genes; - - float fitness; - - // Constructor (makes a random DNA) - DNA(int num) { - genes = new char[num]; - for (int i = 0; i < genes.length; i++) { - genes[i] = (char) random(32,128); // Pick from range of chars - } - } - - // Converts character array to a String - String getPhrase() { - return new String(genes); - } - - // Fitness function (returns floating point % of "correct" characters) - void fitness (String target) { - int score = 0; - for (int i = 0; i < genes.length; i++) { - if (genes[i] == target.charAt(i)) { - score++; - } - } - fitness = (float)score / (float)target.length(); - } - - // Crossover - DNA crossover(DNA partner) { - // A new child - DNA child = new DNA(genes.length); - - int midpoint = int(random(genes.length)); // Pick a midpoint - - // Half from one, half from the other - for (int i = 0; i < genes.length; i++) { - if (i > midpoint) child.genes[i] = genes[i]; - else child.genes[i] = partner.genes[i]; - } - return child; - } - - // Based on a mutation probability, picks a new random character - void mutate(float mutationRate) { - for (int i = 0; i < genes.length; i++) { - if (random(1) < mutationRate) { - genes[i] = (char) random(32,128); - } - } - } -} diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/Population.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/Population.pde deleted file mode 100644 index e8dbe67cd..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/Population.pde +++ /dev/null @@ -1,127 +0,0 @@ -// Genetic Algorithm, Evolving Shakespeare -// Daniel Shiffman - -// A class to describe a population of virtual organisms -// In this case, each organism is just an instance of a DNA object - - - - -class Population { - - float mutationRate; // Mutation rate - DNA[] population; // Array to hold the current population - ArrayList matingPool; // ArrayList which we will use for our "mating pool" - String target; // Target phrase - int generations; // Number of generations - boolean finished; // Are we finished evolving? -int perfectScore; - - Population(String p, float m, int num) { - target = p; - mutationRate = m; - population = new DNA[num]; - for (int i = 0; i < population.length; i++) { - population[i] = new DNA(target.length()); - } - calcFitness(); - matingPool = new ArrayList(); - finished = false; - generations = 0; - - perfectScore = int(pow(2,target.length())); - } - - // Fill our fitness array with a value for every member of the population - void calcFitness() { - for (int i = 0; i < population.length; i++) { - population[i].fitness(target); - } - } - - // Generate a mating pool - void naturalSelection() { - // Clear the ArrayList - matingPool.clear(); - - float maxFitness = 0; - for (int i = 0; i < population.length; i++) { - if (population[i].fitness > maxFitness) { - maxFitness = population[i].fitness; - } - } - - // Based on fitness, each member will get added to the mating pool a certain number of times - // a higher fitness = more entries to mating pool = more likely to be picked as a parent - // a lower fitness = fewer entries to mating pool = less likely to be picked as a parent - for (int i = 0; i < population.length; i++) { - - float fitness = map(population[i].fitness,0,maxFitness,0,1); - int n = int(fitness * 100); // Arbitrary multiplier, we can also use monte carlo method - for (int j = 0; j < n; j++) { // and pick two random numbers - matingPool.add(population[i]); - } - } - } - - // Create a new generation - void generate() { - // Refill the population with children from the mating pool - for (int i = 0; i < population.length; i++) { - int a = int(random(matingPool.size())); - int b = int(random(matingPool.size())); - DNA partnerA = matingPool.get(a); - DNA partnerB = matingPool.get(b); - DNA child = partnerA.crossover(partnerB); - child.mutate(mutationRate); - population[i] = child; - } - generations++; - } - - - // Compute the current "most fit" member of the population - String getBest() { - float worldrecord = 0.0f; - int index = 0; - for (int i = 0; i < population.length; i++) { - if (population[i].fitness > worldrecord) { - index = i; - worldrecord = population[i].fitness; - } - } - - if (worldrecord == perfectScore ) finished = true; - return population[index].getPhrase(); - } - - boolean finished() { - return finished; - } - - int getGenerations() { - return generations; - } - - // Compute average fitness for the population - float getAverageFitness() { - float total = 0; - for (int i = 0; i < population.length; i++) { - total += population[i].fitness; - } - return total / (population.length); - } - - String allPhrases() { - String everything = ""; - - int displayLimit = min(population.length,50); - - - for (int i = 0; i < displayLimit; i++) { - everything += population[i].getPhrase() + "\n"; - } - return everything; - } -} - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/_9_01_GA_Shakespeare.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/_9_01_GA_Shakespeare.pde deleted file mode 100644 index b8831e6c8..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/_9_01_GA_Shakespeare.pde +++ /dev/null @@ -1,87 +0,0 @@ -// Genetic Algorithm, Evolving Shakespeare -// Daniel Shiffman - -// Demonstration of using a genetic algorithm to perform a search - -// setup() -// # Step 1: The Population -// # Create an empty population (an array or ArrayList) -// # Fill it with DNA encoded objects (pick random values to start) - -// draw() -// # Step 1: Selection -// # Create an empty mating pool (an empty ArrayList) -// # For every member of the population, evaluate its fitness based on some criteria / function, -// and add it to the mating pool in a manner consistant with its fitness, i.e. the more fit it -// is the more times it appears in the mating pool, in order to be more likely picked for reproduction. - -// # Step 2: Reproduction Create a new empty population -// # Fill the new population by executing the following steps: -// 1. Pick two "parent" objects from the mating pool. -// 2. Crossover -- create a "child" object by mating these two parents. -// 3. Mutation -- mutate the child's DNA based on a given probability. -// 4. Add the child object to the new population. -// # Replace the old population with the new population -// -// # Rinse and repeat - - -PFont f; -String target; -int popmax; -float mutationRate; -Population population; - -void setup() { - size(800, 200); - f = createFont("Courier", 32, true); - target = "To be or not to be."; - popmax = 150; - mutationRate = 0.01; - - // Create a populationation with a target phrase, mutation rate, and populationation max - population = new Population(target, mutationRate, popmax); -} - -void draw() { - // Generate mating pool - population.naturalSelection(); - //Create next generation - population.generate(); - // Calculate fitness - population.calcFitness(); - displayInfo(); - - // If we found the target phrase, stop - if (population.finished()) { - println(millis()/1000.0); - noLoop(); - } -} - -void displayInfo() { - background(255); - // Display current status of populationation - String answer = population.getBest(); - textFont(f); - textAlign(LEFT); - fill(0); - - - textSize(16); - text("Best phrase:",20,30); - textSize(32); - text(answer, 20, 75); - - textSize(12); - text("total generations: " + population.getGenerations(), 20, 140); - text("average fitness: " + nf(population.getAverageFitness(), 0, 2), 20, 155); - text("total populationation: " + popmax, 20, 170); - text("mutation rate: " + int(mutationRate * 100) + "%", 20, 185); - - textSize(10); - text("All phrases:\n" + population.allPhrases(), 650, 10); -} - - - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/sketch.properties b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/sketch.properties deleted file mode 100644 index b3cbe600e..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/sketch.properties +++ /dev/null @@ -1,2 +0,0 @@ -mode.id=processing.mode.java.JavaMode -mode=Standard diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/web-export/_9_01_GA_Shakespeare.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/web-export/_9_01_GA_Shakespeare.pde deleted file mode 100644 index c82307e42..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/web-export/_9_01_GA_Shakespeare.pde +++ /dev/null @@ -1,282 +0,0 @@ -// Genetic Algorithm, Evolving Shakespeare -// Daniel Shiffman - -// Demonstration of using a genetic algorithm to perform a search - -// setup() -// # Step 1: The Population -// # Create an empty population (an array or ArrayList) -// # Fill it with DNA encoded objects (pick random values to start) - -// draw() -// # Step 1: Selection -// # Create an empty mating pool (an empty ArrayList) -// # For every member of the population, evaluate its fitness based on some criteria / function, -// and add it to the mating pool in a manner consistant with its fitness, i.e. the more fit it -// is the more times it appears in the mating pool, in order to be more likely picked for reproduction. - -// # Step 2: Reproduction Create a new empty population -// # Fill the new population by executing the following steps: -// 1. Pick two "parent" objects from the mating pool. -// 2. Crossover -- create a "child" object by mating these two parents. -// 3. Mutation -- mutate the child's DNA based on a given probability. -// 4. Add the child object to the new population. -// # Replace the old population with the new population -// -// # Rinse and repeat - - -PFont f; -String target; -int popmax; -float mutationRate; -Population population; - -void setup() { - size(800, 200); - f = createFont("Courier", 32, true); - target = "To be or not to be."; - popmax = 150; - mutationRate = 0.01; - - // Create a populationation with a target phrase, mutation rate, and populationation max - population = new Population(target, mutationRate, popmax); -} - -void draw() { - // Generate mating pool - population.naturalSelection(); - //Create next generation - population.generate(); - // Calculate fitness - population.calcFitness(); - displayInfo(); - - // If we found the target phrase, stop - if (population.finished()) { - println(millis()/1000.0); - noLoop(); - } -} - -void displayInfo() { - background(255); - // Display current status of populationation - String answer = population.getBest(); - textFont(f); - textAlign(LEFT); - fill(0); - - - textSize(16); - text("Best phrase:",20,30); - textSize(32); - text(answer, 20, 75); - - textSize(12); - text("total generations: " + population.getGenerations(), 20, 140); - text("average fitness: " + nf(population.getAverageFitness(), 0, 2), 20, 155); - text("total populationation: " + popmax, 20, 170); - text("mutation rate: " + int(mutationRate * 100) + "%", 20, 185); - - textSize(10); - text("All phrases:\n" + population.allPhrases(), 650, 10); -} - - - -// Genetic Algorithm, Evolving Shakespeare -// Daniel Shiffman - -// A class to describe a psuedo-DNA, i.e. genotype -// Here, a virtual organism's DNA is an array of character. -// Functionality: -// -- convert DNA into a string -// -- calculate DNA's "fitness" -// -- mate DNA with another set of DNA -// -- mutate DNA - - -class DNA { - - // The genetic sequence - char[] genes; - - float fitness; - - // Constructor (makes a random DNA) - DNA(int num) { - genes = new char[num]; - for (int i = 0; i < genes.length; i++) { - genes[i] = (char) random(32,128); // Pick from range of chars - } - } - - // Converts character array to a String - String getPhrase() { - return new String(genes); - } - - // Fitness function (returns floating point % of "correct" characters) - void fitness (String target) { - int score = 0; - for (int i = 0; i < genes.length; i++) { - if (genes[i] == target.charAt(i)) { - score++; - } - } - fitness = (float)score / (float)target.length(); - } - - // Crossover - DNA crossover(DNA partner) { - // A new child - DNA child = new DNA(genes.length); - - int midpoint = int(random(genes.length)); // Pick a midpoint - - // Half from one, half from the other - for (int i = 0; i < genes.length; i++) { - if (i > midpoint) child.genes[i] = genes[i]; - else child.genes[i] = partner.genes[i]; - } - return child; - } - - // Based on a mutation probability, picks a new random character - void mutate(float mutationRate) { - for (int i = 0; i < genes.length; i++) { - if (random(1) < mutationRate) { - genes[i] = (char) random(32,128); - } - } - } -} -// Genetic Algorithm, Evolving Shakespeare -// Daniel Shiffman - -// A class to describe a population of virtual organisms -// In this case, each organism is just an instance of a DNA object - - - - -class Population { - - float mutationRate; // Mutation rate - DNA[] population; // Array to hold the current population - ArrayList matingPool; // ArrayList which we will use for our "mating pool" - String target; // Target phrase - int generations; // Number of generations - boolean finished; // Are we finished evolving? -int perfectScore; - - Population(String p, float m, int num) { - target = p; - mutationRate = m; - population = new DNA[num]; - for (int i = 0; i < population.length; i++) { - population[i] = new DNA(target.length()); - } - calcFitness(); - matingPool = new ArrayList(); - finished = false; - generations = 0; - - perfectScore = int(pow(2,target.length())); - } - - // Fill our fitness array with a value for every member of the population - void calcFitness() { - for (int i = 0; i < population.length; i++) { - population[i].fitness(target); - } - } - - // Generate a mating pool - void naturalSelection() { - // Clear the ArrayList - matingPool.clear(); - - float maxFitness = 0; - for (int i = 0; i < population.length; i++) { - if (population[i].fitness > maxFitness) { - maxFitness = population[i].fitness; - } - } - - // Based on fitness, each member will get added to the mating pool a certain number of times - // a higher fitness = more entries to mating pool = more likely to be picked as a parent - // a lower fitness = fewer entries to mating pool = less likely to be picked as a parent - for (int i = 0; i < population.length; i++) { - - float fitness = map(population[i].fitness,0,maxFitness,0,1); - int n = int(fitness * 100); // Arbitrary multiplier, we can also use monte carlo method - for (int j = 0; j < n; j++) { // and pick two random numbers - matingPool.add(population[i]); - } - } - } - - // Create a new generation - void generate() { - // Refill the population with children from the mating pool - for (int i = 0; i < population.length; i++) { - int a = int(random(matingPool.size())); - int b = int(random(matingPool.size())); - DNA partnerA = matingPool.get(a); - DNA partnerB = matingPool.get(b); - DNA child = partnerA.crossover(partnerB); - child.mutate(mutationRate); - population[i] = child; - } - generations++; - } - - - // Compute the current "most fit" member of the population - String getBest() { - float worldrecord = 0.0f; - int index = 0; - for (int i = 0; i < population.length; i++) { - if (population[i].fitness > worldrecord) { - index = i; - worldrecord = population[i].fitness; - } - } - - if (worldrecord == perfectScore ) finished = true; - return population[index].getPhrase(); - } - - boolean finished() { - return finished; - } - - int getGenerations() { - return generations; - } - - // Compute average fitness for the population - float getAverageFitness() { - float total = 0; - for (int i = 0; i < population.length; i++) { - total += population[i].fitness; - } - return total / (population.length); - } - - String allPhrases() { - String everything = ""; - - int displayLimit = min(population.length,50); - - - for (int i = 0; i < displayLimit; i++) { - everything += population[i].getPhrase() + "\n"; - } - return everything; - } -} - - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/web-export/processing.js b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/web-export/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare/web-export/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare_simplified/DNA.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare_simplified/DNA.pde deleted file mode 100644 index faa7c3ebf..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare_simplified/DNA.pde +++ /dev/null @@ -1,67 +0,0 @@ -// Genetic Algorithm, Evolving Shakespeare -// Daniel Shiffman - -// A class to describe a psuedo-DNA, i.e. genotype -// Here, a virtual organism's DNA is an array of character. -// Functionality: -// -- convert DNA into a string -// -- calculate DNA's "fitness" -// -- mate DNA with another set of DNA -// -- mutate DNA - - -class DNA { - - // The genetic sequence - char[] genes; - - float fitness; - - // Constructor (makes a random DNA) - DNA(int num) { - genes = new char[num]; - for (int i = 0; i < genes.length; i++) { - genes[i] = (char) random(32,128); // Pick from range of chars - } - } - - // Converts character array to a String - String getPhrase() { - return new String(genes); - } - - // Fitness function (returns floating point % of "correct" characters) - void calcFitness (String target) { - int score = 0; - for (int i = 0; i < genes.length; i++) { - if (genes[i] == target.charAt(i)) { - score++; - } - } - fitness = (float)score / (float)target.length(); - } - - // Crossover - DNA crossover(DNA partner) { - // A new child - DNA child = new DNA(genes.length); - - int midpoint = int(random(genes.length)); // Pick a midpoint - - // Half from one, half from the other - for (int i = 0; i < genes.length; i++) { - if (i > midpoint) child.genes[i] = genes[i]; - else child.genes[i] = partner.genes[i]; - } - return child; - } - - // Based on a mutation probability, picks a new random character - void mutate(float mutationRate) { - for (int i = 0; i < genes.length; i++) { - if (random(1) < mutationRate) { - genes[i] = (char) random(32,128); - } - } - } -} diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare_simplified/_9_01_GA_Shakespeare_simplified.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare_simplified/_9_01_GA_Shakespeare_simplified.pde deleted file mode 100644 index f78e8237a..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare_simplified/_9_01_GA_Shakespeare_simplified.pde +++ /dev/null @@ -1,86 +0,0 @@ -// Genetic Algorithm, Evolving Shakespeare -// Daniel Shiffman - -// Demonstration of using a genetic algorithm to perform a search - -// setup() -// # Step 1: The Population -// # Create an empty population (an array or ArrayList) -// # Fill it with DNA encoded objects (pick random values to start) - -// draw() -// # Step 1: Selection -// # Create an empty mating pool (an empty ArrayList) -// # For every member of the population, evaluate its fitness based on some criteria / function, -// and add it to the mating pool in a manner consistant with its fitness, i.e. the more fit it -// is the more times it appears in the mating pool, in order to be more likely picked for reproduction. - -// # Step 2: Reproduction Create a new empty population -// # Fill the new population by executing the following steps: -// 1. Pick two "parent" objects from the mating pool. -// 2. Crossover -- create a "child" object by mating these two parents. -// 3. Mutation -- mutate the child's DNA based on a given probability. -// 4. Add the child object to the new population. -// # Replace the old population with the new population -// -// # Rinse and repeat - - -float mutationRate = 0.01; // Mutation rate -int totalPopulation = 150; // Total Population - -DNA[] population; // Array to hold the current population -ArrayList matingPool; // ArrayList which we will use for our "mating pool" -String target; // Target phrase - -PFont f; - -void setup() { - size(800, 200); - target = "To be or not to be."; - - population = new DNA[totalPopulation]; - - for (int i = 0; i < population.length; i++) { - population[i] = new DNA(target.length()); - } - - f = createFont("Courier",12,true); -} - -void draw() { - for (int i = 0; i < population.length; i++) { - population[i].calcFitness(target); - } - - ArrayList matingPool = new ArrayList(); // ArrayList which we will use for our "mating pool" - - for (int i = 0; i < population.length; i++) { - int nnnn = int(population[i].fitness * 100); // Arbitrary multiplier, we can also use monte carlo method - for (int j = 0; j - -// Demonstration of using a genetic algorithm to perform a search - -// setup() -// # Step 1: The Population -// # Create an empty population (an array or ArrayList) -// # Fill it with DNA encoded objects (pick random values to start) - -// draw() -// # Step 1: Selection -// # Create an empty mating pool (an empty ArrayList) -// # For every member of the population, evaluate its fitness based on some criteria / function, -// and add it to the mating pool in a manner consistant with its fitness, i.e. the more fit it -// is the more times it appears in the mating pool, in order to be more likely picked for reproduction. - -// # Step 2: Reproduction Create a new empty population -// # Fill the new population by executing the following steps: -// 1. Pick two "parent" objects from the mating pool. -// 2. Crossover -- create a "child" object by mating these two parents. -// 3. Mutation -- mutate the child's DNA based on a given probability. -// 4. Add the child object to the new population. -// # Replace the old population with the new population -// -// # Rinse and repeat - - -float mutationRate = 0.01; // Mutation rate -int totalPopulation = 150; // Total Population - -DNA[] population; // Array to hold the current population -ArrayList matingPool; // ArrayList which we will use for our "mating pool" -String target; // Target phrase - -PFont f; - -void setup() { - size(800, 200); - target = "To be or not to be."; - - population = new DNA[totalPopulation]; - - for (int i = 0; i < population.length; i++) { - population[i] = new DNA(target.length()); - } - - f = createFont("Courier",12,true); -} - -void draw() { - for (int i = 0; i < population.length; i++) { - population[i].calcFitness(target); - } - - ArrayList matingPool = new ArrayList(); // ArrayList which we will use for our "mating pool" - - for (int i = 0; i < population.length; i++) { - int nnnn = int(population[i].fitness * 100); // Arbitrary multiplier, we can also use monte carlo method - for (int j = 0; j - -// A class to describe a psuedo-DNA, i.e. genotype -// Here, a virtual organism's DNA is an array of character. -// Functionality: -// -- convert DNA into a string -// -- calculate DNA's "fitness" -// -- mate DNA with another set of DNA -// -- mutate DNA - - -class DNA { - - // The genetic sequence - char[] genes; - - float fitness; - - // Constructor (makes a random DNA) - DNA(int num) { - genes = new char[num]; - for (int i = 0; i < genes.length; i++) { - genes[i] = (char) random(32,128); // Pick from range of chars - } - } - - // Converts character array to a String - String getPhrase() { - return new String(genes); - } - - // Fitness function (returns floating point % of "correct" characters) - void calcFitness (String target) { - int score = 0; - for (int i = 0; i < genes.length; i++) { - if (genes[i] == target.charAt(i)) { - score++; - } - } - fitness = (float)score / (float)target.length(); - } - - // Crossover - DNA crossover(DNA partner) { - // A new child - DNA child = new DNA(genes.length); - - int midpoint = int(random(genes.length)); // Pick a midpoint - - // Half from one, half from the other - for (int i = 0; i < genes.length; i++) { - if (i > midpoint) child.genes[i] = genes[i]; - else child.genes[i] = partner.genes[i]; - } - return child; - } - - // Based on a mutation probability, picks a new random character - void mutate(float mutationRate) { - for (int i = 0; i < genes.length; i++) { - if (random(1) < mutationRate) { - genes[i] = (char) random(32,128); - } - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare_simplified/web-export/processing.js b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare_simplified/web-export/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_01_GA_Shakespeare_simplified/web-export/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_02_SmartRockets_superbasic/DNA.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_02_SmartRockets_superbasic/DNA.pde deleted file mode 100644 index c71c4b0ae..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_02_SmartRockets_superbasic/DNA.pde +++ /dev/null @@ -1,57 +0,0 @@ -// Pathfinding w/ Genetic Algorithms -// Daniel Shiffman - -// DNA is an array of vectors - -class DNA { - - // The genetic sequence - PVector[] genes; - - // The maximum strength of the forces - float maxforce = 0.1; - - // Constructor (makes a DNA of random PVectors) - DNA() { - genes = new PVector[lifetime]; - for (int i = 0; i < genes.length; i++) { - float angle = random(TWO_PI); - genes[i] = new PVector(cos(angle), sin(angle)); - genes[i].mult(random(0, maxforce)); - } - } - - // Constructor #2, creates the instance based on an existing array - DNA(PVector[] newgenes) { - // We could make a copy if necessary - // genes = (PVector []) newgenes.clone(); - genes = newgenes; - } - - // CROSSOVER - // Creates new DNA sequence from two (this & and a partner) - DNA crossover(DNA partner) { - PVector[] child = new PVector[genes.length]; - // Pick a midpoint - int crossover = int(random(genes.length)); - // Take "half" from one and "half" from the other - for (int i = 0; i < genes.length; i++) { - if (i > crossover) child[i] = genes[i]; - else child[i] = partner.genes[i]; - } - DNA newgenes = new DNA(child); - return newgenes; - } - - // Based on a mutation probability, picks a new random Vector - void mutate(float m) { - for (int i = 0; i < genes.length; i++) { - if (random(1) < m) { - float angle = random(TWO_PI); - genes[i] = new PVector(cos(angle), sin(angle)); - genes[i].mult(random(0, maxforce)); - } - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_02_SmartRockets_superbasic/Population.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_02_SmartRockets_superbasic/Population.pde deleted file mode 100644 index 3a1cce530..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_02_SmartRockets_superbasic/Population.pde +++ /dev/null @@ -1,100 +0,0 @@ -// Pathfinding w/ Genetic Algorithms -// Daniel Shiffman - -// A class to describe a population of "creatures" - -class Population { - - float mutationRate; // Mutation rate - Rocket[] population; // Array to hold the current population - ArrayList matingPool; // ArrayList which we will use for our "mating pool" - int generations; // Number of generations - - // Initialize the population - Population(float m, int num) { - mutationRate = m; - population = new Rocket[num]; - matingPool = new ArrayList(); - generations = 0; - //make a new set of creatures - for (int i = 0; i < population.length; i++) { - PVector location = new PVector(width/2,height+20); - population[i] = new Rocket(location, new DNA()); - } - } - - void live () { - // Run every rocket - for (int i = 0; i < population.length; i++) { - population[i].run(); - } - } - - // Calculate fitness for each creature - void fitness() { - for (int i = 0; i < population.length; i++) { - population[i].fitness(); - } - } - - // Generate a mating pool - void selection() { - // Clear the ArrayList - matingPool.clear(); - - // Calculate total fitness of whole population - float maxFitness = getMaxFitness(); - - // Calculate fitness for each member of the population (scaled to value between 0 and 1) - // Based on fitness, each member will get added to the mating pool a certain number of times - // A higher fitness = more entries to mating pool = more likely to be picked as a parent - // A lower fitness = fewer entries to mating pool = less likely to be picked as a parent - for (int i = 0; i < population.length; i++) { - float fitnessNormal = map(population[i].getFitness(),0,maxFitness,0,1); - int n = (int) (fitnessNormal * 100); // Arbitrary multiplier - for (int j = 0; j < n; j++) { - matingPool.add(population[i]); - } - } - } - - // Making the next generation - void reproduction() { - // Refill the population with children from the mating pool - for (int i = 0; i < population.length; i++) { - // Sping the wheel of fortune to pick two parents - int m = int(random(matingPool.size())); - int d = int(random(matingPool.size())); - // Pick two parents - Rocket mom = matingPool.get(m); - Rocket dad = matingPool.get(d); - // Get their genes - DNA momgenes = mom.getDNA(); - DNA dadgenes = dad.getDNA(); - // Mate their genes - DNA child = momgenes.crossover(dadgenes); - // Mutate their genes - child.mutate(mutationRate); - // Fill the new population with the new child - PVector location = new PVector(width/2,height+20); - population[i] = new Rocket(location, child); - } - generations++; - } - - int getGenerations() { - return generations; - } - - // Find highest fintess for the population - float getMaxFitness() { - float record = 0; - for (int i = 0; i < population.length; i++) { - if(population[i].getFitness() > record) { - record = population[i].getFitness(); - } - } - return record; - } - -} diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_02_SmartRockets_superbasic/Rocket.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_02_SmartRockets_superbasic/Rocket.pde deleted file mode 100644 index e9a77323a..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_02_SmartRockets_superbasic/Rocket.pde +++ /dev/null @@ -1,105 +0,0 @@ -// Pathfinding w/ Genetic Algorithms -// Daniel Shiffman - -// Rocket class -- this is just like our Boid / Particle class -// the only difference is that it has DNA & fitness - -class Rocket { - - // All of our physics stuff - PVector location; - PVector velocity; - PVector acceleration; - - // Size - float r; - - // Fitness and DNA - float fitness; - DNA dna; - // To count which force we're on in the genes - int geneCounter = 0; - - boolean hitTarget = false; // Did I reach the target - - //constructor - Rocket(PVector l, DNA dna_) { - acceleration = new PVector(); - velocity = new PVector(); - location = l.get(); - r = 4; - dna = dna_; - } - - // Fitness function - // fitness = one divided by distance squared - void fitness() { - float d = dist(location.x, location.y, target.x, target.y); - fitness = pow(1/d, 2); - } - - // Run in relation to all the obstacles - // If I'm stuck, don't bother updating or checking for intersection - void run() { - checkTarget(); // Check to see if we've reached the target - if (!hitTarget) { - applyForce(dna.genes[geneCounter]); - geneCounter = (geneCounter + 1) % dna.genes.length; - update(); - } - display(); - } - - // Did I make it to the target? - void checkTarget() { - float d = dist(location.x, location.y, target.x, target.y); - if (d < 12) { - hitTarget = true; - } - } - - void applyForce(PVector f) { - acceleration.add(f); - } - - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - } - - void display() { - float theta = velocity.heading2D() + PI/2; - fill(200, 100); - stroke(0); - pushMatrix(); - translate(location.x, location.y); - rotate(theta); - - // Thrusters - rectMode(CENTER); - fill(0); - rect(-r/2, r*2, r/2, r); - rect(r/2, r*2, r/2, r); - - // Rocket body - fill(175); - beginShape(TRIANGLES); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(); - - popMatrix(); - } - - float getFitness() { - return fitness; - } - - DNA getDNA() { - return dna; - } - -} - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_02_SmartRockets_superbasic/_9_02_SmartRockets_superbasic.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_02_SmartRockets_superbasic/_9_02_SmartRockets_superbasic.pde deleted file mode 100644 index 5271ef73b..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_02_SmartRockets_superbasic/_9_02_SmartRockets_superbasic.pde +++ /dev/null @@ -1,73 +0,0 @@ -// Smart Rockets w/ Genetic Algorithms -// Daniel Shiffman - -// Each Rocket's DNA is an array of PVectors -// Each PVector acts as a force for each frame of animation -// Imagine an booster on the end of the rocket that can point in any direction -// and fire at any strength every frame - -// The Rocket's fitness is a function of how close it gets to the target as well as how fast it gets there - -// This example is inspired by Jer Thorp's Smart Rockets -// http://www.blprnt.com/smartrockets/ - -int lifetime; // How long should each generation live - -Population population; // Population - -int lifeCounter; // Timer for cycle of generation - -PVector target; // Target location - -void setup() { - size(800, 200); - smooth(); - - // The number of cycles we will allow a generation to live - lifetime = 200; - - // Initialize variables - lifeCounter = 0; - - target = new PVector(width/2, 24); - - // Create a population with a mutation rate, and population max - float mutationRate = 0.01; - population = new Population(mutationRate, 50); - -} - -void draw() { - background(255); - - // Draw the start and target locations - fill(0); - ellipse(target.x,target.y,24,24); - - - // If the generation hasn't ended yet - if (lifeCounter < lifetime) { - population.live(); - lifeCounter++; - // Otherwise a new generation - } - else { - lifeCounter = 0; - population.fitness(); - population.selection(); - population.reproduction(); - } - - // Display some info - fill(0); - text("Generation #: " + population.getGenerations(), 10, 18); - text("Cycles left: " + (lifetime-lifeCounter), 10, 36); -} - -// Move the target if the mouse is pressed -// System will adapt to new target -void mousePressed() { - target.x = mouseX; - target.y = mouseY; -} - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/DNA.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/DNA.pde deleted file mode 100644 index 6243526f1..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/DNA.pde +++ /dev/null @@ -1,65 +0,0 @@ -// Pathfinding w/ Genetic Algorithms -// Daniel Shiffman - -// DNA is an array of vectors - -class DNA { - - // The genetic sequence - PVector[] genes; - - // The maximum strength of the forces - float maxforce = 0.1; - - // Constructor (makes a DNA of random PVectors) - DNA() { - genes = new PVector[lifetime]; - for (int i = 0; i < genes.length; i++) { - float angle = random(TWO_PI); - genes[i] = new PVector(cos(angle), sin(angle)); - genes[i].mult(random(0, maxforce)); - } - - // Let's give each Rocket an extra boost of strength for its first frame - genes[0].normalize(); - } - - // Constructor #2, creates the instance based on an existing array - DNA(PVector[] newgenes) { - // We could make a copy if necessary - // genes = (PVector []) newgenes.clone(); - genes = newgenes; - } - - // CROSSOVER - // Creates new DNA sequence from two (this & and a partner) - DNA crossover(DNA partner) { - PVector[] child = new PVector[genes.length]; - // Pick a midpoint - int crossover = int(random(genes.length)); - // Take "half" from one and "half" from the other - for (int i = 0; i < genes.length; i++) { - if (i > crossover) child[i] = genes[i]; - else child[i] = partner.genes[i]; - } - DNA newgenes = new DNA(child); - return newgenes; - } - - // Based on a mutation probability, picks a new random Vector - void mutate(float m) { - for (int i = 0; i < genes.length; i++) { - if (random(1) < m) { - float angle = random(TWO_PI); - genes[i] = new PVector(cos(angle), sin(angle)); - genes[i].mult(random(0, maxforce)); - // float angle = random(-0.1,0.1); - // genes[i].rotate(angle); - // float factor = random(0.9,1.1); - // genes[i].mult(factor); - if (i ==0) genes[i].normalize(); - } - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/Obstacle.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/Obstacle.pde deleted file mode 100644 index e8d4207b6..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/Obstacle.pde +++ /dev/null @@ -1,37 +0,0 @@ -// Pathfinding w/ Genetic Algorithms -// Daniel Shiffman - -// A class for an obstacle, just a simple rectangle that is drawn -// and can check if a Rocket touches it - -// Also using this class for target location - - -class Obstacle { - - PVector location; - float w,h; - - Obstacle(float x, float y, float w_, float h_) { - location = new PVector(x,y); - w = w_; - h = h_; - } - - void display() { - stroke(0); - fill(175); - strokeWeight(2); - rectMode(CORNER); - rect(location.x,location.y,w,h); - } - - boolean contains(PVector spot) { - if (spot.x > location.x && spot.x < location.x + w && spot.y > location.y && spot.y < location.y + h) { - return true; - } else { - return false; - } - } - -} diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/Population.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/Population.pde deleted file mode 100644 index b5a8ccbed..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/Population.pde +++ /dev/null @@ -1,110 +0,0 @@ -// Pathfinding w/ Genetic Algorithms -// Daniel Shiffman - -// A class to describe a population of "creatures" - -class Population { - - float mutationRate; // Mutation rate - Rocket[] population; // Array to hold the current population - ArrayList matingPool; // ArrayList which we will use for our "mating pool" - int generations; // Number of generations - - // Initialize the population - Population(float m, int num) { - mutationRate = m; - population = new Rocket[num]; - matingPool = new ArrayList(); - generations = 0; - //make a new set of creatures - for (int i = 0; i < population.length; i++) { - PVector location = new PVector(width/2,height+20); - population[i] = new Rocket(location, new DNA(),population.length); - } - } - - void live (ArrayList os) { - // For every creature - for (int i = 0; i < population.length; i++) { - // If it finishes, mark it down as done! - population[i].checkTarget(); - population[i].run(os); - } - } - - // Did anything finish? - boolean targetReached() { - for (int i = 0; i < population.length; i++) { - if (population[i].hitTarget) return true; - } - return false; - } - - // Calculate fitness for each creature - void fitness() { - for (int i = 0; i < population.length; i++) { - population[i].fitness(); - } - } - - // Generate a mating pool - void selection() { - // Clear the ArrayList - matingPool.clear(); - - // Calculate total fitness of whole population - float maxFitness = getMaxFitness(); - - // Calculate fitness for each member of the population (scaled to value between 0 and 1) - // Based on fitness, each member will get added to the mating pool a certain number of times - // A higher fitness = more entries to mating pool = more likely to be picked as a parent - // A lower fitness = fewer entries to mating pool = less likely to be picked as a parent - for (int i = 0; i < population.length; i++) { - float fitnessNormal = map(population[i].getFitness(),0,maxFitness,0,1); - int n = (int) (fitnessNormal * 100); // Arbitrary multiplier - for (int j = 0; j < n; j++) { - matingPool.add(population[i]); - } - } - } - - // Making the next generation - void reproduction() { - // Refill the population with children from the mating pool - for (int i = 0; i < population.length; i++) { - // Sping the wheel of fortune to pick two parents - int m = int(random(matingPool.size())); - int d = int(random(matingPool.size())); - // Pick two parents - Rocket mom = matingPool.get(m); - Rocket dad = matingPool.get(d); - // Get their genes - DNA momgenes = mom.getDNA(); - DNA dadgenes = dad.getDNA(); - // Mate their genes - DNA child = momgenes.crossover(dadgenes); - // Mutate their genes - child.mutate(mutationRate); - // Fill the new population with the new child - PVector location = new PVector(width/2,height+20); - population[i] = new Rocket(location, child,population.length); - } - generations++; - } - - int getGenerations() { - return generations; - } - - // Find highest fintess for the population - float getMaxFitness() { - float record = 0; - for (int i = 0; i < population.length; i++) { - if(population[i].getFitness() > record) { - record = population[i].getFitness(); - } - } - return record; - } - -} diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/Rocket.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/Rocket.pde deleted file mode 100644 index 488b9ea9e..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/Rocket.pde +++ /dev/null @@ -1,147 +0,0 @@ -// Pathfinding w/ Genetic Algorithms -// Daniel Shiffman - -// Rocket class -- this is just like our Boid / Particle class -// the only difference is that it has DNA & fitness - -class Rocket { - - // All of our physics stuff - PVector location; - PVector velocity; - PVector acceleration; - - // Size - float r; - - // How close did it get to the target - float recordDist; - - // Fitness and DNA - float fitness; - DNA dna; - // To count which force we're on in the genes - int geneCounter = 0; - - boolean hitObstacle = false; // Am I stuck on an obstacle? - boolean hitTarget = false; // Did I reach the target - int finishTime; // What was my finish time? - - //constructor - Rocket(PVector l, DNA dna_, int totalRockets) { - acceleration = new PVector(); - velocity = new PVector(); - location = l.get(); - r = 4; - dna = dna_; - finishTime = 0; // We're going to count how long it takes to reach target - recordDist = 10000; // Some high number that will be beat instantly - } - - // FITNESS FUNCTION - // distance = distance from target - // finish = what order did i finish (first, second, etc. . .) - // f(distance,finish) = (1.0f / finish^1.5) * (1.0f / distance^6); - // a lower finish is rewarded (exponentially) and/or shorter distance to target (exponetially) - void fitness() { - if (recordDist < 1) recordDist = 1; - - // Reward finishing faster and getting close - fitness = (1/(finishTime*recordDist)); - - // Make the function exponential - fitness = pow(fitness, 4); - - if (hitObstacle) fitness *= 0.1; // lose 90% of fitness hitting an obstacle - if (hitTarget) fitness *= 2; // twice the fitness for finishing! - } - - // Run in relation to all the obstacles - // If I'm stuck, don't bother updating or checking for intersection - void run(ArrayList os) { - if (!hitObstacle && !hitTarget) { - applyForce(dna.genes[geneCounter]); - geneCounter = (geneCounter + 1) % dna.genes.length; - update(); - // If I hit an edge or an obstacle - obstacles(os); - } - // Draw me! - if (!hitObstacle) { - display(); - } - } - - // Did I make it to the target? - void checkTarget() { - float d = dist(location.x, location.y, target.location.x, target.location.y); - if (d < recordDist) recordDist = d; - - if (target.contains(location) && !hitTarget) { - hitTarget = true; - } - else if (!hitTarget) { - finishTime++; - } - } - - // Did I hit an obstacle? - void obstacles(ArrayList os) { - for (Obstacle obs : os) { - if (obs.contains(location)) { - hitObstacle = true; - } - } - } - - void applyForce(PVector f) { - acceleration.add(f); - } - - - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - } - - void display() { - //background(255,0,0); - float theta = velocity.heading2D() + PI/2; - fill(200, 100); - stroke(0); - strokeWeight(1); - pushMatrix(); - translate(location.x, location.y); - rotate(theta); - - // Thrusters - rectMode(CENTER); - fill(0); - rect(-r/2, r*2, r/2, r); - rect(r/2, r*2, r/2, r); - - // Rocket body - fill(175); - beginShape(TRIANGLES); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(); - - popMatrix(); - } - - float getFitness() { - return fitness; - } - - DNA getDNA() { - return dna; - } - - boolean stopped() { - return hitObstacle; - } -} - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/_9_03_SmartRockets.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/_9_03_SmartRockets.pde deleted file mode 100644 index 46f7d6df4..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/_9_03_SmartRockets.pde +++ /dev/null @@ -1,93 +0,0 @@ -// Smart Rockets w/ Genetic Algorithms -// Daniel Shiffman - -// Each Rocket's DNA is an array of PVectors -// Each PVector acts as a force for each frame of animation -// Imagine an booster on the end of the rocket that can point in any direction -// and fire at any strength every frame - -// The Rocket's fitness is a function of how close it gets to the target as well as how fast it gets there - -// This example is inspired by Jer Thorp's Smart Rockets -// http://www.blprnt.com/smartrockets/ - -int lifetime; // How long should each generation live - -Population population; // Population - -int lifecycle; // Timer for cycle of generation -int recordtime; // Fastest time to target - -Obstacle target; // Target location - -//int diam = 24; // Size of target - -ArrayList obstacles; //an array list to keep track of all the obstacles! - -void setup() { - size(800, 200); - smooth(); - - // The number of cycles we will allow a generation to live - lifetime = 300; - - // Initialize variables - lifecycle = 0; - recordtime = lifetime; - - target = new Obstacle(width/2-12, 24, 24, 24); - - // Create a population with a mutation rate, and population max - float mutationRate = 0.01; - population = new Population(mutationRate, 50); - - // Create the obstacle course - obstacles = new ArrayList(); - obstacles.add(new Obstacle(300, height/2, width-600, 10)); -} - -void draw() { - background(255); - - // Draw the start and target locations - target.display(); - - - // If the generation hasn't ended yet - if (lifecycle < lifetime) { - population.live(obstacles); - if ((population.targetReached()) && (lifecycle < recordtime)) { - recordtime = lifecycle; - } - lifecycle++; - // Otherwise a new generation - } - else { - lifecycle = 0; - population.fitness(); - population.selection(); - population.reproduction(); - } - - // Draw the obstacles - for (Obstacle obs : obstacles) { - obs.display(); - } - - // Display some info - fill(0); - text("Generation #: " + population.getGenerations(), 10, 18); - text("Cycles left: " + (lifetime-lifecycle), 10, 36); - text("Record cycles: " + recordtime, 10, 54); - - -} - -// Move the target if the mouse is pressed -// System will adapt to new target -void mousePressed() { - target.location.x = mouseX; - target.location.y = mouseY; - recordtime = lifetime; -} - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/sketch.properties b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/sketch.properties deleted file mode 100644 index 28faa5897..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/sketch.properties +++ /dev/null @@ -1 +0,0 @@ -mode=Standard diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/web-export/_9_03_SmartRockets.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/web-export/_9_03_SmartRockets.pde deleted file mode 100644 index 1d0ac71a3..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/web-export/_9_03_SmartRockets.pde +++ /dev/null @@ -1,453 +0,0 @@ -// Smart Rockets w/ Genetic Algorithms -// Daniel Shiffman - -// Each Rocket's DNA is an array of PVectors -// Each PVector acts as a force for each frame of animation -// Imagine an booster on the end of the rocket that can point in any direction -// and fire at any strength every frame - -// The Rocket's fitness is a function of how close it gets to the target as well as how fast it gets there - -// This example is inspired by Jer Thorp's Smart Rockets -// http://www.blprnt.com/smartrockets/ - -int lifetime; // How long should each generation live - -Population population; // Population - -int lifecycle; // Timer for cycle of generation -int recordtime; // Fastest time to target - -Obstacle target; // Target location - -//int diam = 24; // Size of target - -ArrayList obstacles; //an array list to keep track of all the obstacles! - -void setup() { - size(800, 200); - smooth(); - - // The number of cycles we will allow a generation to live - lifetime = 300; - - // Initialize variables - lifecycle = 0; - recordtime = lifetime; - - target = new Obstacle(width/2-12, 24, 24, 24); - - // Create a population with a mutation rate, and population max - float mutationRate = 0.01; - population = new Population(mutationRate, 50); - - // Create the obstacle course - obstacles = new ArrayList(); - obstacles.add(new Obstacle(300, height/2, width-600, 10)); -} - -void draw() { - background(255); - - // Draw the start and target locations - target.display(); - - - // If the generation hasn't ended yet - if (lifecycle < lifetime) { - population.live(obstacles); - if ((population.targetReached()) && (lifecycle < recordtime)) { - recordtime = lifecycle; - } - lifecycle++; - // Otherwise a new generation - } - else { - lifecycle = 0; - population.fitness(); - population.selection(); - population.reproduction(); - } - - // Draw the obstacles - for (Obstacle obs : obstacles) { - obs.display(); - } - - // Display some info - fill(0); - text("Generation #: " + population.getGenerations(), 10, 18); - text("Cycles left: " + (lifetime-lifecycle), 10, 36); - text("Record cycles: " + recordtime, 10, 54); - - -} - -// Move the target if the mouse is pressed -// System will adapt to new target -void mousePressed() { - target.location.x = mouseX; - target.location.y = mouseY; - recordtime = lifetime; -} - -// Pathfinding w/ Genetic Algorithms -// Daniel Shiffman - -// DNA is an array of vectors - -class DNA { - - // The genetic sequence - PVector[] genes; - - // The maximum strength of the forces - float maxforce = 0.1; - - // Constructor (makes a DNA of random PVectors) - DNA() { - genes = new PVector[lifetime]; - for (int i = 0; i < genes.length; i++) { - float angle = random(TWO_PI); - genes[i] = new PVector(cos(angle), sin(angle)); - genes[i].mult(random(0, maxforce)); - } - - // Let's give each Rocket an extra boost of strength for its first frame - genes[0].normalize(); - } - - // Constructor #2, creates the instance based on an existing array - DNA(PVector[] newgenes) { - // We could make a copy if necessary - // genes = (PVector []) newgenes.clone(); - genes = newgenes; - } - - // CROSSOVER - // Creates new DNA sequence from two (this & and a partner) - DNA crossover(DNA partner) { - PVector[] child = new PVector[genes.length]; - // Pick a midpoint - int crossover = int(random(genes.length)); - // Take "half" from one and "half" from the other - for (int i = 0; i < genes.length; i++) { - if (i > crossover) child[i] = genes[i]; - else child[i] = partner.genes[i]; - } - DNA newgenes = new DNA(child); - return newgenes; - } - - // Based on a mutation probability, picks a new random Vector - void mutate(float m) { - for (int i = 0; i < genes.length; i++) { - if (random(1) < m) { - float angle = random(TWO_PI); - genes[i] = new PVector(cos(angle), sin(angle)); - genes[i].mult(random(0, maxforce)); - // float angle = random(-0.1,0.1); - // genes[i].rotate(angle); - // float factor = random(0.9,1.1); - // genes[i].mult(factor); - if (i ==0) genes[i].normalize(); - } - } - } -} - -// Pathfinding w/ Genetic Algorithms -// Daniel Shiffman - -// A class for an obstacle, just a simple rectangle that is drawn -// and can check if a Rocket touches it - -// Also using this class for target location - - -class Obstacle { - - PVector location; - float w,h; - - Obstacle(float x, float y, float w_, float h_) { - location = new PVector(x,y); - w = w_; - h = h_; - } - - void display() { - stroke(0); - fill(175); - strokeWeight(2); - rectMode(CORNER); - rect(location.x,location.y,w,h); - } - - boolean contains(PVector spot) { - if (spot.x > location.x && spot.x < location.x + w && spot.y > location.y && spot.y < location.y + h) { - return true; - } else { - return false; - } - } - -} -// Pathfinding w/ Genetic Algorithms -// Daniel Shiffman - -// A class to describe a population of "creatures" - -class Population { - - float mutationRate; // Mutation rate - Rocket[] population; // Array to hold the current population - ArrayList matingPool; // ArrayList which we will use for our "mating pool" - int generations; // Number of generations - - // Initialize the population - Population(float m, int num) { - mutationRate = m; - population = new Rocket[num]; - matingPool = new ArrayList(); - generations = 0; - //make a new set of creatures - for (int i = 0; i < population.length; i++) { - PVector location = new PVector(width/2,height+20); - population[i] = new Rocket(location, new DNA(),population.length); - } - } - - void live (ArrayList os) { - // For every creature - for (int i = 0; i < population.length; i++) { - // If it finishes, mark it down as done! - population[i].checkTarget(); - population[i].run(os); - } - } - - // Did anything finish? - boolean targetReached() { - for (int i = 0; i < population.length; i++) { - if (population[i].hitTarget) return true; - } - return false; - } - - // Calculate fitness for each creature - void fitness() { - for (int i = 0; i < population.length; i++) { - population[i].fitness(); - } - } - - // Generate a mating pool - void selection() { - // Clear the ArrayList - matingPool.clear(); - - // Calculate total fitness of whole population - float maxFitness = getMaxFitness(); - - // Calculate fitness for each member of the population (scaled to value between 0 and 1) - // Based on fitness, each member will get added to the mating pool a certain number of times - // A higher fitness = more entries to mating pool = more likely to be picked as a parent - // A lower fitness = fewer entries to mating pool = less likely to be picked as a parent - for (int i = 0; i < population.length; i++) { - float fitnessNormal = map(population[i].getFitness(),0,maxFitness,0,1); - int n = (int) (fitnessNormal * 100); // Arbitrary multiplier - for (int j = 0; j < n; j++) { - matingPool.add(population[i]); - } - } - } - - // Making the next generation - void reproduction() { - // Refill the population with children from the mating pool - for (int i = 0; i < population.length; i++) { - // Sping the wheel of fortune to pick two parents - int m = int(random(matingPool.size())); - int d = int(random(matingPool.size())); - // Pick two parents - Rocket mom = matingPool.get(m); - Rocket dad = matingPool.get(d); - // Get their genes - DNA momgenes = mom.getDNA(); - DNA dadgenes = dad.getDNA(); - // Mate their genes - DNA child = momgenes.crossover(dadgenes); - // Mutate their genes - child.mutate(mutationRate); - // Fill the new population with the new child - PVector location = new PVector(width/2,height+20); - population[i] = new Rocket(location, child,population.length); - } - generations++; - } - - int getGenerations() { - return generations; - } - - // Find highest fintess for the population - float getMaxFitness() { - float record = 0; - for (int i = 0; i < population.length; i++) { - if(population[i].getFitness() > record) { - record = population[i].getFitness(); - } - } - return record; - } - -} -// Pathfinding w/ Genetic Algorithms -// Daniel Shiffman - -// Rocket class -- this is just like our Boid / Particle class -// the only difference is that it has DNA & fitness - -class Rocket { - - // All of our physics stuff - PVector location; - PVector velocity; - PVector acceleration; - - // Size - float r; - - // How close did it get to the target - float recordDist; - - // Fitness and DNA - float fitness; - DNA dna; - // To count which force we're on in the genes - int geneCounter = 0; - - boolean hitObstacle = false; // Am I stuck on an obstacle? - boolean hitTarget = false; // Did I reach the target - int finishTime; // What was my finish time? - - //constructor - Rocket(PVector l, DNA dna_, int totalRockets) { - acceleration = new PVector(); - velocity = new PVector(); - location = l.get(); - r = 4; - dna = dna_; - finishTime = 0; // We're going to count how long it takes to reach target - recordDist = 10000; // Some high number that will be beat instantly - } - - // FITNESS FUNCTION - // distance = distance from target - // finish = what order did i finish (first, second, etc. . .) - // f(distance,finish) = (1.0f / finish^1.5) * (1.0f / distance^6); - // a lower finish is rewarded (exponentially) and/or shorter distance to target (exponetially) - void fitness() { - if (recordDist < 1) recordDist = 1; - - // Reward finishing faster and getting close - fitness = (1/(finishTime*recordDist)); - - // Make the function exponential - fitness = pow(fitness, 4); - - if (hitObstacle) fitness *= 0.1; // lose 90% of fitness hitting an obstacle - if (hitTarget) fitness *= 2; // twice the fitness for finishing! - } - - // Run in relation to all the obstacles - // If I'm stuck, don't bother updating or checking for intersection - void run(ArrayList os) { - if (!hitObstacle && !hitTarget) { - applyForce(dna.genes[geneCounter]); - geneCounter = (geneCounter + 1) % dna.genes.length; - update(); - // If I hit an edge or an obstacle - obstacles(os); - } - // Draw me! - if (!hitObstacle) { - display(); - } - } - - // Did I make it to the target? - void checkTarget() { - float d = dist(location.x, location.y, target.location.x, target.location.y); - if (d < recordDist) recordDist = d; - - if (target.contains(location) && !hitTarget) { - hitTarget = true; - } - else if (!hitTarget) { - finishTime++; - } - } - - // Did I hit an obstacle? - void obstacles(ArrayList os) { - for (Obstacle obs : os) { - if (obs.contains(location)) { - hitObstacle = true; - } - } - } - - void applyForce(PVector f) { - acceleration.add(f); - } - - - void update() { - velocity.add(acceleration); - location.add(velocity); - acceleration.mult(0); - } - - void display() { - //background(255,0,0); - float theta = velocity.heading2D() + PI/2; - fill(200, 100); - stroke(0); - strokeWeight(1); - pushMatrix(); - translate(location.x, location.y); - rotate(theta); - - // Thrusters - rectMode(CENTER); - fill(0); - rect(-r/2, r*2, r/2, r); - rect(r/2, r*2, r/2, r); - - // Rocket body - fill(175); - beginShape(TRIANGLES); - vertex(0, -r*2); - vertex(-r, r*2); - vertex(r, r*2); - endShape(); - - popMatrix(); - } - - float getFitness() { - return fitness; - } - - DNA getDNA() { - return dna; - } - - boolean stopped() { - return hitObstacle; - } -} - - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/web-export/processing.js b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/web-export/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_03_SmartRockets/web-export/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/Button.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/Button.pde deleted file mode 100644 index c7747749a..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/Button.pde +++ /dev/null @@ -1,53 +0,0 @@ -// Interactive Selection -// http://www.genarts.com/karl/papers/siggraph91.html -// Daniel Shiffman - -//import java.awt.Rectangle; - -class Button { - Rectangle r; // Button's rectangle - String txt; // Button's text - boolean clickedOn; // Did i click on it? - boolean rolloverOn; // Did i rollover it? - - Button(int x, int y, int w, int h, String s) { - r = new Rectangle(x,y,w,h); - txt = s; - } - - void display() { - // Draw rectangle and text based on whether rollover or clicked - rectMode(CORNER); - stroke(0); noFill(); - if (rolloverOn) fill(0.5); - if (clickedOn) fill(0); - rect(r.x,r.y,r.width,r.height); - float b = 0.0; - if (clickedOn) b = 1; - else if (rolloverOn) b = 0.2; - else b = 0; - fill(b); - textAlign(LEFT); - text(txt,r.x+10,r.y+14); - - } - - - // Methods to check rollover, clicked, or released (must be called from appropriate - // Places in draw, mousePressed, mouseReleased - boolean rollover(int mx, int my) { - if (r.contains(mx,my)) rolloverOn = true; - else rolloverOn = false; - return rolloverOn; - } - - boolean clicked(int mx, int my) { - if (r.contains(mx,my)) clickedOn = true; - return clickedOn; - } - - void released() { - clickedOn = false; - } - -} diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/DNA.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/DNA.pde deleted file mode 100644 index f5f986159..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/DNA.pde +++ /dev/null @@ -1,46 +0,0 @@ -// Interactive Selection -// http://www.genarts.com/karl/papers/siggraph91.html -// Daniel Shiffman - -class DNA { - - // The genetic sequence - float[] genes; - int len = 20; // Arbitrary length - - //Constructor (makes a random DNA) - DNA() { - // DNA is random floating point values between 0 and 1 (!!) - genes = new float[len]; - for (int i = 0; i < genes.length; i++) { - genes[i] = random(0,1); - } - } - - DNA(float[] newgenes) { - genes = newgenes; - } - - - // Crossover - // Creates new DNA sequence from two (this & - DNA crossover(DNA partner) { - float[] child = new float[genes.length]; - int crossover = int(random(genes.length)); - for (int i = 0; i < genes.length; i++) { - if (i > crossover) child[i] = genes[i]; - else child[i] = partner.genes[i]; - } - DNA newgenes = new DNA(child); - return newgenes; - } - - // Based on a mutation probability, picks a new random character in array spots - void mutate(float m) { - for (int i = 0; i < genes.length; i++) { - if (random(1) < m) { - genes[i] = random(0,1); - } - } - } -} diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/Face.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/Face.pde deleted file mode 100644 index d95dbc7c2..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/Face.pde +++ /dev/null @@ -1,101 +0,0 @@ -// Interactive Selection -// http://www.genarts.com/karl/papers/siggraph91.html -// Daniel Shiffman - -// The class for our "face", contains DNA sequence, fitness value, position on screen - -// Fitness Function f(t) = t (where t is "time" mouse rolls over face) - -class Face { - - DNA dna; // Face's DNA - float fitness; // How good is this face? - float x, y; // Position on screen - int wh = 70; // Size of square enclosing face - boolean rolloverOn; // Are we rolling over this face? - - Rectangle r; - - // Create a new face - Face(DNA dna_, float x_, float y_) { - dna = dna_; - x = x_; - y = y_; - fitness = 1; - // Using java.awt.Rectangle (see: http://java.sun.com/j2se/1.4.2/docs/api/java/awt/Rectangle.html) - r = new Rectangle(int(x-wh/2), int(y-wh/2), int(wh), int(wh)); - } - - // Display the face - void display() { - // We are using the face's DNA to pick properties for this face - // such as: head size, color, eye position, etc. - // Now, since every gene is a floating point between 0 and 1, we map the values - float r = map(dna.genes[0],0,1,0,70); - color c = color(dna.genes[1],dna.genes[2],dna.genes[3]); - float eye_y = map(dna.genes[4],0,1,0,5); - float eye_x = map(dna.genes[5],0,1,0,10); - float eye_size = map(dna.genes[5],0,1,0,10); - color eyecolor = color(dna.genes[4],dna.genes[5],dna.genes[6]); - color mouthColor = color(dna.genes[7],dna.genes[8],dna.genes[9]); - float mouth_y = map(dna.genes[5],0,1,0,25); - float mouth_x = map(dna.genes[5],0,1,-25,25); - float mouthw = map(dna.genes[5],0,1,0,50); - float mouthh = map(dna.genes[5],0,1,0,10); - - // Once we calculate all the above properties, we use those variables to draw rects, ellipses, etc. - pushMatrix(); - translate(x, y); - noStroke(); - - // Draw the head - smooth(); - fill(c); - ellipseMode(CENTER); - ellipse(0, 0, r, r); - - // Draw the eyes - fill(eyecolor); - rectMode(CENTER); - rect(-eye_x, -eye_y, eye_size, eye_size); - rect( eye_x, -eye_y, eye_size, eye_size); - - // Draw the mouth - fill(mouthColor); - rectMode(CENTER); - rect(mouth_x, mouth_y, mouthw, mouthh); - - // Draw the bounding box - stroke(0.25); - if (rolloverOn) fill(0, 0.25); - else noFill(); - rectMode(CENTER); - rect(0, 0, wh, wh); - popMatrix(); - - // Display fitness value - textAlign(CENTER); - if (rolloverOn) fill(0); - else fill(0.25); - text(int(fitness), x, y+55); - } - - float getFitness() { - return fitness; - } - - DNA getDNA() { - return dna; - } - - // Increment fitness if mouse is rolling over face - void rollover(int mx, int my) { - if (r.contains(mx, my)) { - rolloverOn = true; - fitness += 0.25; - } else { - rolloverOn = false; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/Population.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/Population.pde deleted file mode 100644 index f4df91d2a..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/Population.pde +++ /dev/null @@ -1,99 +0,0 @@ -// Interactive Selection -// http://www.genarts.com/karl/papers/siggraph91.html -// Daniel Shiffman - -// A class to describe a population of faces -// this hasn't changed very much from example to example - -class Population { - - float mutationRate; // Mutation rate - Face[] population; // array to hold the current population - ArrayList matingPool; // ArrayList which we will use for our "mating pool" - int generations; // Number of generations - - // Create the population - Population(float m, int num) { - mutationRate = m; - population = new Face[num]; - matingPool = new ArrayList(); - generations = 0; - for (int i = 0; i < population.length; i++) { - population[i] = new Face(new DNA(), 50+i*75, 60); - } - } - - // Display all faces - void display() { - for (int i = 0; i < population.length; i++) { - population[i].display(); - } - } - - // Are we rolling over any of the faces? - void rollover(int mx, int my) { - for (int i = 0; i < population.length; i++) { - population[i].rollover(mx, my); - } - } - - // Generate a mating pool - void selection() { - // Clear the ArrayList - matingPool.clear(); - - // Calculate total fitness of whole population - float maxFitness = getMaxFitness(); - - // Calculate fitness for each member of the population (scaled to value between 0 and 1) - // Based on fitness, each member will get added to the mating pool a certain number of times - // A higher fitness = more entries to mating pool = more likely to be picked as a parent - // A lower fitness = fewer entries to mating pool = less likely to be picked as a parent - for (int i = 0; i < population.length; i++) { - float fitnessNormal = map(population[i].getFitness(), 0, maxFitness, 0, 1); - int n = (int) (fitnessNormal * 100); // Arbitrary multiplier - for (int j = 0; j < n; j++) { - matingPool.add(population[i]); - } - } - } - - // Making the next generation - void reproduction() { - // Refill the population with children from the mating pool - for (int i = 0; i < population.length; i++) { - // Sping the wheel of fortune to pick two parents - int m = int(random(matingPool.size())); - int d = int(random(matingPool.size())); - // Pick two parents - Face mom = matingPool.get(m); - Face dad = matingPool.get(d); - // Get their genes - DNA momgenes = mom.getDNA(); - DNA dadgenes = dad.getDNA(); - // Mate their genes - DNA child = momgenes.crossover(dadgenes); - // Mutate their genes - child.mutate(mutationRate); - // Fill the new population with the new child - population[i] = new Face(child, 50+i*75, 60); - } - generations++; - } - - int getGenerations() { - return generations; - } - - // Find highest fintess for the population - float getMaxFitness() { - float record = 0; - for (int i = 0; i < population.length; i++) { - if (population[i].getFitness() > record) { - record = population[i].getFitness(); - } - } - return record; - } -} - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/Rectangle.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/Rectangle.pde deleted file mode 100644 index 7f6ad9691..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/Rectangle.pde +++ /dev/null @@ -1,21 +0,0 @@ -// Re-implementing java.awt.Rectangle -// so JS mode works - -class Rectangle { - int x; - int y; - int width; - int height; - - Rectangle(int x_, int y_, int w, int h) { - x = x_; - y = y_; - width = w; - height = h; - } - - boolean contains(int px, int py) { - return (px > x && px < x + width && py > y && py < y + height); - } - -} diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/_9_04_Faces_interactiveselection.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/_9_04_Faces_interactiveselection.pde deleted file mode 100644 index 77a1e5af9..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_04_Faces_interactiveselection/_9_04_Faces_interactiveselection.pde +++ /dev/null @@ -1,46 +0,0 @@ -// Interactive Selection -// http://www.genarts.com/karl/papers/siggraph91.html -// Daniel Shiffman - -Population population; -Button button; - -void setup() { - size(800,200); - colorMode(RGB,1.0); - smooth(); - int popmax = 10; - float mutationRate = 0.05; // A pretty high mutation rate here, our population is rather small we need to enforce variety - // Create a population with a target phrase, mutation rate, and population max - population = new Population(mutationRate,popmax); - // A simple button class - button = new Button(15,150,160,20, "evolve new generation"); -} - -void draw() { - background(1.0); - // Display the faces - population.display(); - population.rollover(mouseX,mouseY); - // Display some text - textAlign(LEFT); - fill(0); - text("Generation #:" + population.getGenerations(),15,190); - - // Display the button - button.display(); - button.rollover(mouseX,mouseY); - -} - -// If the button is clicked, evolve next generation -void mousePressed() { - if (button.clicked(mouseX,mouseY)) { - population.selection(); - population.reproduction(); - } -} - -void mouseReleased() { - button.released(); -} diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/Bloop.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/Bloop.pde deleted file mode 100644 index a7f11cfd3..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/Bloop.pde +++ /dev/null @@ -1,105 +0,0 @@ -// Evolution EcoSystem -// Daniel Shiffman - -// Creature class - -class Bloop { - PVector location; // Location - DNA dna; // DNA - float health; // Life timer - float xoff; // For perlin noise - float yoff; - // DNA will determine size and maxspeed - float r; - float maxspeed; - - // Create a "bloop" creature - Bloop(PVector l, DNA dna_) { - location = l.get(); - health = 200; - xoff = random(1000); - yoff = random(1000); - dna = dna_; - // Gene 0 determines maxspeed and r - // The bigger the bloop, the slower it is - maxspeed = map(dna.genes[0], 0, 1, 15, 0); - r = map(dna.genes[0], 0, 1, 0, 50); - } - - void run() { - update(); - borders(); - display(); - } - - // A bloop can find food and eat it - void eat(Food f) { - ArrayList food = f.getFood(); - // Are we touching any food objects? - for (int i = food.size()-1; i >= 0; i--) { - PVector foodLocation = food.get(i); - float d = PVector.dist(location, foodLocation); - // If we are, juice up our strength! - if (d < r/2) { - health += 100; - food.remove(i); - } - } - } - - // At any moment there is a teeny, tiny chance a bloop will reproduce - Bloop reproduce() { - // asexual reproduction - if (random(1) < 0.0005) { - // Child is exact copy of single parent - DNA childDNA = dna.copy(); - // Child DNA can mutate - childDNA.mutate(0.01); - return new Bloop(location, childDNA); - } - else { - return null; - } - } - - // Method to update location - void update() { - // Simple movement based on perlin noise - float vx = map(noise(xoff),0,1,-maxspeed,maxspeed); - float vy = map(noise(yoff),0,1,-maxspeed,maxspeed); - PVector velocity = new PVector(vx,vy); - xoff += 0.01; - yoff += 0.01; - - location.add(velocity); - // Death always looming - health -= 0.2; - } - - // Wraparound - void borders() { - if (location.x < -r) location.x = width+r; - if (location.y < -r) location.y = height+r; - if (location.x > width+r) location.x = -r; - if (location.y > height+r) location.y = -r; - } - - // Method to display - void display() { - ellipseMode(CENTER); - stroke(0,health); - fill(0, health); - ellipse(location.x, location.y, r, r); - } - - // Death - boolean dead() { - if (health < 0.0) { - return true; - } - else { - return false; - } - } -} - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/DNA.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/DNA.pde deleted file mode 100644 index 807e776a7..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/DNA.pde +++ /dev/null @@ -1,44 +0,0 @@ -// Evolution EcoSystem -// Daniel Shiffman - -// Class to describe DNA -// Has more features for two parent mating (not used in this example) - -class DNA { - - // The genetic sequence - float[] genes; - - // Constructor (makes a random DNA) - DNA() { - // DNA is random floating point values between 0 and 1 (!!) - genes = new float[1]; - for (int i = 0; i < genes.length; i++) { - genes[i] = random(0,1); - } - } - - DNA(float[] newgenes) { - genes = newgenes; - } - - DNA copy() { - float[] newgenes = new float[genes.length]; - //arraycopy(genes,newgenes); - // JS mode not supporting arraycopy - for (int i = 0; i < newgenes.length; i++) { - newgenes[i] = genes[i]; - } - - return new DNA(newgenes); - } - - // Based on a mutation probability, picks a new random character in array spots - void mutate(float m) { - for (int i = 0; i < genes.length; i++) { - if (random(1) < m) { - genes[i] = random(0,1); - } - } - } -} diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/Food.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/Food.pde deleted file mode 100644 index e94bd5a0a..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/Food.pde +++ /dev/null @@ -1,41 +0,0 @@ -// Evolution EcoSystem -// Daniel Shiffman - -// A collection of food in the world - -class Food { - ArrayList food; - - Food(int num) { - // Start with some food - food = new ArrayList(); - for (int i = 0; i < num; i++) { - food.add(new PVector(random(width),random(height))); - } - } - - // Add some food at a location - void add(PVector l) { - food.add(l.get()); - } - - // Display the food - void run() { - for (PVector f : food) { - rectMode(CENTER); - stroke(0); - fill(175); - rect(f.x,f.y,8,8); - } - - // There's a small chance food will appear randomly - if (random(1) < 0.001) { - food.add(new PVector(random(width),random(height))); - } - } - - // Return the list of food - ArrayList getFood() { - return food; - } -} diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/World.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/World.pde deleted file mode 100644 index d3edc5dd8..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/World.pde +++ /dev/null @@ -1,56 +0,0 @@ -// Evolution EcoSystem -// Daniel Shiffman -// Spring 2007, The Nature of Code - -// The World we live in -// Has bloops and food - -class World { - - ArrayList bloops; // An arraylist for all the creatures - Food food; - - // Constructor - World(int num) { - // Start with initial food and creatures - food = new Food(num); - bloops = new ArrayList(); // Initialize the arraylist - for (int i = 0; i < num; i++) { - PVector l = new PVector(random(width),random(height)); - DNA dna = new DNA(); - bloops.add(new Bloop(l,dna)); - } - } - - // Make a new creature - void born(float x, float y) { - PVector l = new PVector(x,y); - DNA dna = new DNA(); - bloops.add(new Bloop(l,dna)); - } - - // Run the world - void run() { - // Deal with food - food.run(); - - // Cycle through the ArrayList backwards b/c we are deleting - for (int i = bloops.size()-1; i >= 0; i--) { - // All bloops run and eat - Bloop b = bloops.get(i); - b.run(); - b.eat(food); - // If it's dead, kill it and make food - if (b.dead()) { - bloops.remove(i); - food.add(b.location); - } - // Perhaps this bloop would like to make a baby? - Bloop child = b.reproduce(); - if (child != null) bloops.add(child); - } - } -} - - - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/_9_05_EvolutionEcosystem.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/_9_05_EvolutionEcosystem.pde deleted file mode 100644 index f92a22e37..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/_9_05_EvolutionEcosystem.pde +++ /dev/null @@ -1,33 +0,0 @@ -// Evolution EcoSystem -// Daniel Shiffman -// The Nature of Code - -// A World of creatures that eat food -// The more they eat, the longer they survive -// The longer they survive, the more likely they are to reproduce -// The bigger they are, the easier it is to land on food -// The bigger they are, the slower they are to find food -// When the creatures die, food is left behind - - -World world; - -void setup() { - size(800, 200); - // World starts with 20 creatures - // and 20 pieces of food - world = new World(20); - smooth(); -} - -void draw() { - background(255); - world.run(); -} - -// We can add a creature manually if we so desire -void mousePressed() { - world.born(mouseX,mouseY); -} - - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/sketch.properties b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/sketch.properties deleted file mode 100644 index 28faa5897..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/sketch.properties +++ /dev/null @@ -1 +0,0 @@ -mode=Standard diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/web-export/_9_05_EvolutionEcosystem.pde b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/web-export/_9_05_EvolutionEcosystem.pde deleted file mode 100644 index 5680a8b7e..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/web-export/_9_05_EvolutionEcosystem.pde +++ /dev/null @@ -1,280 +0,0 @@ -// Evolution EcoSystem -// Daniel Shiffman -// The Nature of Code - -// A World of creatures that eat food -// The more they eat, the longer they survive -// The longer they survive, the more likely they are to reproduce -// The bigger they are, the easier it is to land on food -// The bigger they are, the slower they are to find food -// When the creatures die, food is left behind - - -World world; - -void setup() { - size(800, 200); - // World starts with 20 creatures - // and 20 pieces of food - world = new World(20); - smooth(); -} - -void draw() { - background(255); - world.run(); -} - -// We can add a creature manually if we so desire -void mousePressed() { - world.born(mouseX,mouseY); -} - - -// Evolution EcoSystem -// Daniel Shiffman - -// Creature class - -class Bloop { - PVector location; // Location - DNA dna; // DNA - float health; // Life timer - float xoff; // For perlin noise - float yoff; - // DNA will determine size and maxspeed - float r; - float maxspeed; - - // Create a "bloop" creature - Bloop(PVector l, DNA dna_) { - location = l.get(); - health = 200; - xoff = random(1000); - yoff = random(1000); - dna = dna_; - // Gene 0 determines maxspeed and r - // The bigger the bloop, the slower it is - maxspeed = map(dna.genes[0], 0, 1, 15, 0); - r = map(dna.genes[0], 0, 1, 0, 50); - } - - void run() { - update(); - borders(); - display(); - } - - // A bloop can find food and eat it - void eat(Food f) { - ArrayList food = f.getFood(); - // Are we touching any food objects? - for (int i = food.size()-1; i >= 0; i--) { - PVector foodLocation = food.get(i); - float d = PVector.dist(location, foodLocation); - // If we are, juice up our strength! - if (d < r/2) { - health += 100; - food.remove(i); - } - } - } - - // At any moment there is a teeny, tiny chance a bloop will reproduce - Bloop reproduce() { - // asexual reproduction - if (random(1) < 0.0005) { - // Child is exact copy of single parent - DNA childDNA = dna.copy(); - // Child DNA can mutate - childDNA.mutate(0.01); - return new Bloop(location, childDNA); - } - else { - return null; - } - } - - // Method to update location - void update() { - // Simple movement based on perlin noise - float vx = map(noise(xoff),0,1,-maxspeed,maxspeed); - float vy = map(noise(yoff),0,1,-maxspeed,maxspeed); - PVector velocity = new PVector(vx,vy); - xoff += 0.01; - yoff += 0.01; - - location.add(velocity); - // Death always looming - health -= 0.2; - } - - // Wraparound - void borders() { - if (location.x < -r) location.x = width+r; - if (location.y < -r) location.y = height+r; - if (location.x > width+r) location.x = -r; - if (location.y > height+r) location.y = -r; - } - - // Method to display - void display() { - ellipseMode(CENTER); - stroke(0,health); - fill(0, health); - ellipse(location.x, location.y, r, r); - } - - // Death - boolean dead() { - if (health < 0.0) { - return true; - } - else { - return false; - } - } -} - -// Evolution EcoSystem -// Daniel Shiffman - -// Class to describe DNA -// Has more features for two parent mating (not used in this example) - -class DNA { - - // The genetic sequence - float[] genes; - - // Constructor (makes a random DNA) - DNA() { - // DNA is random floating point values between 0 and 1 (!!) - genes = new float[1]; - for (int i = 0; i < genes.length; i++) { - genes[i] = random(0,1); - } - } - - DNA(float[] newgenes) { - genes = newgenes; - } - - DNA copy() { - float[] newgenes = new float[genes.length]; - //arraycopy(genes,newgenes); - // JS mode not supporting arraycopy - for (int i = 0; i < newgenes.length; i++) { - newgenes[i] = genes[i]; - } - - return new DNA(newgenes); - } - - // Based on a mutation probability, picks a new random character in array spots - void mutate(float m) { - for (int i = 0; i < genes.length; i++) { - if (random(1) < m) { - genes[i] = random(0,1); - } - } - } -} -// Evolution EcoSystem -// Daniel Shiffman - -// A collection of food in the world - -class Food { - ArrayList food; - - Food(int num) { - // Start with some food - food = new ArrayList(); - for (int i = 0; i < num; i++) { - food.add(new PVector(random(width),random(height))); - } - } - - // Add some food at a location - void add(PVector l) { - food.add(l.get()); - } - - // Display the food - void run() { - for (PVector f : food) { - rectMode(CENTER); - stroke(0); - fill(175); - rect(f.x,f.y,8,8); - } - - // There's a small chance food will appear randomly - if (random(1) < 0.001) { - food.add(new PVector(random(width),random(height))); - } - } - - // Return the list of food - ArrayList getFood() { - return food; - } -} -// Evolution EcoSystem -// Daniel Shiffman -// Spring 2007, The Nature of Code - -// The World we live in -// Has bloops and food - -class World { - - ArrayList bloops; // An arraylist for all the creatures - Food food; - - // Constructor - World(int num) { - // Start with initial food and creatures - food = new Food(num); - bloops = new ArrayList(); // Initialize the arraylist - for (int i = 0; i < num; i++) { - PVector l = new PVector(random(width),random(height)); - DNA dna = new DNA(); - bloops.add(new Bloop(l,dna)); - } - } - - // Make a new creature - void born(float x, float y) { - PVector l = new PVector(x,y); - DNA dna = new DNA(); - bloops.add(new Bloop(l,dna)); - } - - // Run the world - void run() { - // Deal with food - food.run(); - - // Cycle through the ArrayList backwards b/c we are deleting - for (int i = bloops.size()-1; i >= 0; i--) { - // All bloops run and eat - Bloop b = bloops.get(i); - b.run(); - b.eat(food); - // If it's dead, kill it and make food - if (b.dead()) { - bloops.remove(i); - food.add(b.location); - } - // Perhaps this bloop would like to make a baby? - Bloop child = b.reproduce(); - if (child != null) bloops.add(child); - } - } -} - - - - diff --git a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/web-export/processing.js b/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/web-export/processing.js deleted file mode 100644 index 45c550fdd..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/NOC_9_05_EvolutionEcosystem/web-export/processing.js +++ /dev/null @@ -1,9994 +0,0 @@ -/*** - - P R O C E S S I N G . J S - 1.3.6 - a port of the Processing visualization language - - Processing.js is licensed under the MIT License, see LICENSE. - For a list of copyright holders, please refer to AUTHORS. - - http://processingjs.org - -***/ - -(function(window, document, Math, undef) { - var nop = function() {}; - var debug = function() { - if ("console" in window) return function(msg) { - window.console.log("Processing.js: " + msg) - }; - return nop() - }(); - var ajax = function(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null); - if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status; - return xhr.responseText - }; - var isDOMPresent = "document" in this && !("fake" in this.document); - document.head = document.head || document.getElementsByTagName("head")[0]; - - function setupTypedArray(name, fallback) { - if (name in window) return window[name]; - if (typeof window[fallback] === "function") return window[fallback]; - return function(obj) { - if (obj instanceof Array) return obj; - if (typeof obj === "number") { - var arr = []; - arr.length = obj; - return arr - } - } - } - var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), - Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), - Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), - Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); - var PConstants = { - X: 0, - Y: 1, - Z: 2, - R: 3, - G: 4, - B: 5, - A: 6, - U: 7, - V: 8, - NX: 9, - NY: 10, - NZ: 11, - EDGE: 12, - SR: 13, - SG: 14, - SB: 15, - SA: 16, - SW: 17, - TX: 18, - TY: 19, - TZ: 20, - VX: 21, - VY: 22, - VZ: 23, - VW: 24, - AR: 25, - AG: 26, - AB: 27, - DR: 3, - DG: 4, - DB: 5, - DA: 6, - SPR: 28, - SPG: 29, - SPB: 30, - SHINE: 31, - ER: 32, - EG: 33, - EB: 34, - BEEN_LIT: 35, - VERTEX_FIELD_COUNT: 36, - P2D: 1, - JAVA2D: 1, - WEBGL: 2, - P3D: 2, - OPENGL: 2, - PDF: 0, - DXF: 0, - OTHER: 0, - WINDOWS: 1, - MAXOSX: 2, - LINUX: 3, - EPSILON: 1.0E-4, - MAX_FLOAT: 3.4028235E38, - MIN_FLOAT: -3.4028235E38, - MAX_INT: 2147483647, - MIN_INT: -2147483648, - PI: Math.PI, - TWO_PI: 2 * Math.PI, - HALF_PI: Math.PI / 2, - THIRD_PI: Math.PI / 3, - QUARTER_PI: Math.PI / 4, - DEG_TO_RAD: Math.PI / 180, - RAD_TO_DEG: 180 / Math.PI, - WHITESPACE: " \t\n\r\u000c\u00a0", - RGB: 1, - ARGB: 2, - HSB: 3, - ALPHA: 4, - CMYK: 5, - TIFF: 0, - TARGA: 1, - JPEG: 2, - GIF: 3, - BLUR: 11, - GRAY: 12, - INVERT: 13, - OPAQUE: 14, - POSTERIZE: 15, - THRESHOLD: 16, - ERODE: 17, - DILATE: 18, - REPLACE: 0, - BLEND: 1 << 0, - ADD: 1 << 1, - SUBTRACT: 1 << 2, - LIGHTEST: 1 << 3, - DARKEST: 1 << 4, - DIFFERENCE: 1 << 5, - EXCLUSION: 1 << 6, - MULTIPLY: 1 << 7, - SCREEN: 1 << 8, - OVERLAY: 1 << 9, - HARD_LIGHT: 1 << 10, - SOFT_LIGHT: 1 << 11, - DODGE: 1 << 12, - BURN: 1 << 13, - ALPHA_MASK: 4278190080, - RED_MASK: 16711680, - GREEN_MASK: 65280, - BLUE_MASK: 255, - CUSTOM: 0, - ORTHOGRAPHIC: 2, - PERSPECTIVE: 3, - POINT: 2, - POINTS: 2, - LINE: 4, - LINES: 4, - TRIANGLE: 8, - TRIANGLES: 9, - TRIANGLE_STRIP: 10, - TRIANGLE_FAN: 11, - QUAD: 16, - QUADS: 16, - QUAD_STRIP: 17, - POLYGON: 20, - PATH: 21, - RECT: 30, - ELLIPSE: 31, - ARC: 32, - SPHERE: 40, - BOX: 41, - GROUP: 0, - PRIMITIVE: 1, - GEOMETRY: 3, - VERTEX: 0, - BEZIER_VERTEX: 1, - CURVE_VERTEX: 2, - BREAK: 3, - CLOSESHAPE: 4, - OPEN: 1, - CLOSE: 2, - CORNER: 0, - CORNERS: 1, - RADIUS: 2, - CENTER_RADIUS: 2, - CENTER: 3, - DIAMETER: 3, - CENTER_DIAMETER: 3, - BASELINE: 0, - TOP: 101, - BOTTOM: 102, - NORMAL: 1, - NORMALIZED: 1, - IMAGE: 2, - MODEL: 4, - SHAPE: 5, - SQUARE: "butt", - ROUND: "round", - PROJECT: "square", - MITER: "miter", - BEVEL: "bevel", - AMBIENT: 0, - DIRECTIONAL: 1, - SPOT: 3, - BACKSPACE: 8, - TAB: 9, - ENTER: 10, - RETURN: 13, - ESC: 27, - DELETE: 127, - CODED: 65535, - SHIFT: 16, - CONTROL: 17, - ALT: 18, - CAPSLK: 20, - PGUP: 33, - PGDN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLK: 144, - META: 157, - INSERT: 155, - ARROW: "default", - CROSS: "crosshair", - HAND: "pointer", - MOVE: "move", - TEXT: "text", - WAIT: "wait", - NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto", - DISABLE_OPENGL_2X_SMOOTH: 1, - ENABLE_OPENGL_2X_SMOOTH: -1, - ENABLE_OPENGL_4X_SMOOTH: 2, - ENABLE_NATIVE_FONTS: 3, - DISABLE_DEPTH_TEST: 4, - ENABLE_DEPTH_TEST: -4, - ENABLE_DEPTH_SORT: 5, - DISABLE_DEPTH_SORT: -5, - DISABLE_OPENGL_ERROR_REPORT: 6, - ENABLE_OPENGL_ERROR_REPORT: -6, - ENABLE_ACCURATE_TEXTURES: 7, - DISABLE_ACCURATE_TEXTURES: -7, - HINT_COUNT: 10, - SINCOS_LENGTH: 720, - PRECISIONB: 15, - PRECISIONF: 1 << 15, - PREC_MAXVAL: (1 << 15) - 1, - PREC_ALPHA_SHIFT: 24 - 15, - PREC_RED_SHIFT: 16 - 15, - NORMAL_MODE_AUTO: 0, - NORMAL_MODE_SHAPE: 1, - NORMAL_MODE_VERTEX: 2, - MAX_LIGHTS: 8 - }; - - function virtHashCode(obj) { - if (typeof obj === "string") { - var hash = 0; - for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; - return hash - } - if (typeof obj !== "object") return obj & 4294967295; - if (obj.hashCode instanceof Function) return obj.hashCode(); - if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536); - return obj.$id - } - function virtEquals(obj, other) { - if (obj === null || other === null) return obj === null && other === null; - if (typeof obj === "string") return obj === other; - if (typeof obj !== "object") return obj === other; - if (obj.equals instanceof Function) return obj.equals(other); - return obj === other - } - var ObjectIterator = function(obj) { - if (obj.iterator instanceof Function) return obj.iterator(); - if (obj instanceof Array) { - var index = -1; - this.hasNext = function() { - return ++index < obj.length - }; - this.next = function() { - return obj[index] - } - } else throw "Unable to iterate: " + obj; - }; - var ArrayList = function() { - function Iterator(array) { - var index = 0; - this.hasNext = function() { - return index < array.length - }; - this.next = function() { - return array[index++] - }; - this.remove = function() { - array.splice(index, 1) - } - } - function ArrayList() { - var array; - if (arguments.length === 0) array = []; - else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray(); - else { - array = []; - array.length = 0 | arguments[0] - } - this.get = function(i) { - return array[i] - }; - this.contains = function(item) { - return this.indexOf(item) > -1 - }; - this.indexOf = function(item) { - for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; - return -1 - }; - this.add = function() { - if (arguments.length === 1) array.push(arguments[0]); - else if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]); - else throw arg0 + " is not a valid index"; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.addAll = function(arg1, arg2) { - var it; - if (typeof arg1 === "number") { - if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; - it = new ObjectIterator(arg2); - while (it.hasNext()) array.splice(arg1++, 0, it.next()) - } else { - it = new ObjectIterator(arg1); - while (it.hasNext()) array.push(it.next()) - } - }; - this.set = function() { - if (arguments.length === 2) { - var arg0 = arguments[0]; - if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]); - else throw arg0 + " is not a valid index."; - else throw typeof arg0 + " is not a number"; - } else throw "Please use the proper number of parameters."; - }; - this.size = function() { - return array.length - }; - this.clear = function() { - array.length = 0 - }; - this.remove = function(item) { - if (typeof item === "number") return array.splice(item, 1)[0]; - item = this.indexOf(item); - if (item > -1) { - array.splice(item, 1); - return true - } - return false - }; - this.isEmpty = function() { - return !array.length - }; - this.clone = function() { - return new ArrayList(this) - }; - this.toArray = function() { - return array.slice(0) - }; - this.iterator = function() { - return new Iterator(array) - } - } - return ArrayList - }(); - var HashMap = function() { - function HashMap() { - if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); - var initialCapacity = arguments.length > 0 ? arguments[0] : 16; - var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; - var buckets = []; - buckets.length = initialCapacity; - var count = 0; - var hashMap = this; - - function getBucketIndex(key) { - var index = virtHashCode(key) % buckets.length; - return index < 0 ? buckets.length + index : index - } - function ensureLoad() { - if (count <= loadFactor * buckets.length) return; - var allEntries = []; - for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]); - var newBucketsLength = buckets.length * 2; - buckets = []; - buckets.length = newBucketsLength; - for (var j = 0; j < allEntries.length; ++j) { - var index = getBucketIndex(allEntries[j].key); - var bucket = buckets[index]; - if (bucket === undef) buckets[index] = bucket = []; - bucket.push(allEntries[j]) - } - } - function Iterator(conversion, removeItem) { - var bucketIndex = 0; - var itemIndex = -1; - var endOfBuckets = false; - - function findNext() { - while (!endOfBuckets) { - ++itemIndex; - if (bucketIndex >= buckets.length) endOfBuckets = true; - else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) { - itemIndex = -1; - ++bucketIndex - } else return - } - } - this.hasNext = function() { - return !endOfBuckets - }; - this.next = function() { - var result = conversion(buckets[bucketIndex][itemIndex]); - findNext(); - return result - }; - this.remove = function() { - removeItem(this.next()); - --itemIndex - }; - findNext() - } - function Set(conversion, isIn, removeItem) { - this.clear = function() { - hashMap.clear() - }; - this.contains = function(o) { - return isIn(o) - }; - this.containsAll = function(o) { - var it = o.iterator(); - while (it.hasNext()) if (!this.contains(it.next())) return false; - return true - }; - this.isEmpty = function() { - return hashMap.isEmpty() - }; - this.iterator = function() { - return new Iterator(conversion, removeItem) - }; - this.remove = function(o) { - if (this.contains(o)) { - removeItem(o); - return true - } - return false - }; - this.removeAll = function(c) { - var it = c.iterator(); - var changed = false; - while (it.hasNext()) { - var item = it.next(); - if (this.contains(item)) { - removeItem(item); - changed = true - } - } - return true - }; - this.retainAll = function(c) { - var it = this.iterator(); - var toRemove = []; - while (it.hasNext()) { - var entry = it.next(); - if (!c.contains(entry)) toRemove.push(entry) - } - for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]); - return toRemove.length > 0 - }; - this.size = function() { - return hashMap.size() - }; - this.toArray = function() { - var result = []; - var it = this.iterator(); - while (it.hasNext()) result.push(it.next()); - return result - } - } - function Entry(pair) { - this._isIn = function(map) { - return map === hashMap && pair.removed === undef - }; - this.equals = function(o) { - return virtEquals(pair.key, o.getKey()) - }; - this.getKey = function() { - return pair.key - }; - this.getValue = function() { - return pair.value - }; - this.hashCode = function(o) { - return virtHashCode(pair.key) - }; - this.setValue = function(value) { - var old = pair.value; - pair.value = value; - return old - } - } - this.clear = function() { - count = 0; - buckets = []; - buckets.length = initialCapacity - }; - this.clone = function() { - var map = new HashMap; - map.putAll(this); - return map - }; - this.containsKey = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return false; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true; - return false - }; - this.containsValue = function(value) { - for (var i = 0; i < buckets.length; ++i) { - var bucket = buckets[i]; - if (bucket === undef) continue; - for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true - } - return false - }; - this.entrySet = function() { - return new Set(function(pair) { - return new Entry(pair) - }, - - - function(pair) { - return pair instanceof Entry && pair._isIn(hashMap) - }, - - - function(pair) { - return hashMap.remove(pair.getKey()) - }) - }; - this.get = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value; - return null - }; - this.isEmpty = function() { - return count === 0 - }; - this.keySet = function() { - return new Set(function(pair) { - return pair.key - }, - - - function(key) { - return hashMap.containsKey(key) - }, - - - function(key) { - return hashMap.remove(key) - }) - }; - this.values = function() { - return new Set(function(pair) { - return pair.value - }, - - - function(value) { - return hashMap.containsValue(value) - }, - - function(value) { - return hashMap.removeByValue(value) - }) - }; - this.put = function(key, value) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) { - ++count; - buckets[index] = [{ - key: key, - value: value - }]; - ensureLoad(); - return null - } - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - var previous = bucket[i].value; - bucket[i].value = value; - return previous - }++count; - bucket.push({ - key: key, - value: value - }); - ensureLoad(); - return null - }; - this.putAll = function(m) { - var it = m.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - this.put(entry.getKey(), entry.getValue()) - } - }; - this.remove = function(key) { - var index = getBucketIndex(key); - var bucket = buckets[index]; - if (bucket === undef) return null; - for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) { - --count; - var previous = bucket[i].value; - bucket[i].removed = true; - if (bucket.length > 1) bucket.splice(i, 1); - else buckets[index] = undef; - return previous - } - return null - }; - this.removeByValue = function(value) { - var bucket, i, ilen, pair; - for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { - pair = buckets[bucket][i]; - if (pair.value === value) { - buckets[bucket].splice(i, 1); - return true - } - } - return false - }; - this.size = function() { - return count - } - } - return HashMap - }(); - var PVector = function() { - function PVector(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0 - } - PVector.dist = function(v1, v2) { - return v1.dist(v2) - }; - PVector.dot = function(v1, v2) { - return v1.dot(v2) - }; - PVector.cross = function(v1, v2) { - return v1.cross(v2) - }; - PVector.angleBetween = function(v1, v2) { - return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag())) - }; - PVector.prototype = { - set: function(v, y, z) { - if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); - else { - this.x = v; - this.y = y; - this.z = z - } - }, - get: function() { - return new PVector(this.x, this.y, this.z) - }, - mag: function() { - var x = this.x, - y = this.y, - z = this.z; - return Math.sqrt(x * x + y * y + z * z) - }, - add: function(v, y, z) { - if (arguments.length === 1) { - this.x += v.x; - this.y += v.y; - this.z += v.z - } else { - this.x += v; - this.y += y; - this.z += z - } - }, - sub: function(v, y, z) { - if (arguments.length === 1) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z - } else { - this.x -= v; - this.y -= y; - this.z -= z - } - }, - mult: function(v) { - if (typeof v === "number") { - this.x *= v; - this.y *= v; - this.z *= v - } else { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z - } - }, - div: function(v) { - if (typeof v === "number") { - this.x /= v; - this.y /= v; - this.z /= v - } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z - } - }, - dist: function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - }, - dot: function(v, y, z) { - if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z; - return this.x * v + this.y * y + this.z * z - }, - cross: function(v) { - var x = this.x, - y = this.y, - z = this.z; - return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y) - }, - normalize: function() { - var m = this.mag(); - if (m > 0) this.div(m) - }, - limit: function(high) { - if (this.mag() > high) { - this.normalize(); - this.mult(high) - } - }, - heading2D: function() { - return -Math.atan2(-this.y, this.x) - }, - toString: function() { - return "[" + this.x + ", " + this.y + ", " + this.z + "]" - }, - array: function() { - return [this.x, this.y, this.z] - } - }; - - function createPVectorMethod(method) { - return function(v1, v2) { - var v = v1.get(); - v[method](v2); - return v - } - } - for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method); - return PVector - }(); - - function DefaultScope() {} - DefaultScope.prototype = PConstants; - var defaultScope = new DefaultScope; - defaultScope.ArrayList = ArrayList; - defaultScope.HashMap = HashMap; - defaultScope.PVector = PVector; - defaultScope.ObjectIterator = ObjectIterator; - defaultScope.PConstants = PConstants; - defaultScope.defineProperty = function(obj, name, desc) { - if ("defineProperty" in Object) Object.defineProperty(obj, name, desc); - else { - if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get); - if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set) - } - }; - - function extendClass(subClass, baseClass) { - function extendGetterSetter(propertyName) { - defaultScope.defineProperty(subClass, propertyName, { - get: function() { - return baseClass[propertyName] - }, - set: function(v) { - baseClass[propertyName] = v - }, - enumerable: true - }) - } - var properties = []; - for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") { - if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName] - } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); - while (properties.length > 0) extendGetterSetter(properties.shift()) - } - defaultScope.extendClassChain = function(base) { - var path = [base]; - for (var self = base.$upcast; self; self = self.$upcast) { - extendClass(self, base); - path.push(self); - base = self - } - while (path.length > 0) path.pop().$self = base - }; - defaultScope.extendStaticMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.extendInterfaceMembers = function(derived, base) { - extendClass(derived, base) - }; - defaultScope.addMethod = function(object, name, fn, superAccessor) { - if (object[name]) { - var args = fn.length, - oldfn = object[name]; - object[name] = function() { - if (arguments.length === args) return fn.apply(this, arguments); - return oldfn.apply(this, arguments) - } - } else object[name] = fn - }; - defaultScope.createJavaArray = function(type, bounds) { - var result = null; - if (typeof bounds[0] === "number") { - var itemsCount = 0 | bounds[0]; - if (bounds.length <= 1) { - result = []; - result.length = itemsCount; - for (var i = 0; i < itemsCount; ++i) result[i] = 0 - } else { - result = []; - var newBounds = bounds.slice(1); - for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) - } - } - return result - }; - var colors = { - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgrey: "#d3d3d3", - lightgreen: "#90ee90", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370d8", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#d87093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }; - (function(Processing) { - var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), - count = unsupportedP5.length, - prettyName, p5Name; - - function createUnsupportedFunc(n) { - return function() { - throw "Processing.js does not support " + n + "."; - } - } - while (count--) { - prettyName = unsupportedP5[count]; - p5Name = prettyName.replace("()", ""); - Processing[p5Name] = createUnsupportedFunc(prettyName) - } - })(defaultScope); - defaultScope.defineProperty(defaultScope, "screenWidth", { - get: function() { - return window.innerWidth - } - }); - defaultScope.defineProperty(defaultScope, "screenHeight", { - get: function() { - return window.innerHeight - } - }); - var processingInstances = []; - var processingInstanceIds = {}; - var removeInstance = function(id) { - processingInstances.splice(processingInstanceIds[id], 1); - delete processingInstanceIds[id] - }; - var addInstance = function(processing) { - if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; - processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; - processingInstances.push(processing) - }; - - function computeFontMetrics(pfont) { - var emQuad = 250, - correctionFactor = pfont.size / emQuad, - canvas = document.createElement("canvas"); - canvas.width = 2 * emQuad; - canvas.height = 2 * emQuad; - canvas.style.opacity = 0; - var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), - ctx = canvas.getContext("2d"); - ctx.font = cfmFont; - pfont.context2d = ctx; - var protrusions = "dbflkhyjqpg"; - canvas.width = ctx.measureText(protrusions).width; - ctx.font = cfmFont; - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.fontFamily = '"' + pfont.name + '"'; - leadDiv.style.fontSize = emQuad + "px"; - leadDiv.innerHTML = protrusions + "
" + protrusions; - document.body.appendChild(leadDiv); - var w = canvas.width, - h = canvas.height, - baseline = h / 2; - ctx.fillStyle = "white"; - ctx.fillRect(0, 0, w, h); - ctx.fillStyle = "black"; - ctx.fillText(protrusions, 0, baseline); - var pixelData = ctx.getImageData(0, 0, w, h).data; - var i = 0, - w4 = w * 4, - len = pixelData.length; - while (++i < len && pixelData[i] === 255) nop(); - var ascent = Math.round(i / w4); - i = len - 1; - while (--i > 0 && pixelData[i] === 255) nop(); - var descent = Math.round(i / w4); - pfont.ascent = correctionFactor * (baseline - ascent); - pfont.descent = correctionFactor * (descent - baseline); - if (document.defaultView.getComputedStyle) { - var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); - leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); - if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) - } - document.body.removeChild(leadDiv) - } - function PFont(name, size) { - if (name === undef) name = ""; - this.name = name; - if (size === undef) size = 0; - this.size = size; - this.glyph = false; - this.ascent = 0; - this.descent = 0; - this.leading = 1.2 * size; - var illegalIndicator = name.indexOf(" Italic Bold"); - if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); - this.style = "normal"; - var italicsIndicator = name.indexOf(" Italic"); - if (italicsIndicator !== -1) { - name = name.substring(0, italicsIndicator); - this.style = "italic" - } - this.weight = "normal"; - var boldIndicator = name.indexOf(" Bold"); - if (boldIndicator !== -1) { - name = name.substring(0, boldIndicator); - this.weight = "bold" - } - this.family = "sans-serif"; - if (name !== undef) switch (name) { - case "sans-serif": - case "serif": - case "monospace": - case "fantasy": - case "cursive": - this.family = name; - break; - default: - this.family = '"' + name + '", sans-serif'; - break - } - this.context2d = null; - computeFontMetrics(this); - this.css = this.getCSSDefinition(); - this.context2d.font = this.css - } - PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { - if (fontSize === undef) fontSize = this.size + "px"; - if (lineHeight === undef) lineHeight = this.leading + "px"; - var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; - return components.join(" ") - }; - PFont.prototype.measureTextWidth = function(string) { - return this.context2d.measureText(string).width - }; - PFont.PFontCache = {}; - PFont.get = function(fontName, fontSize) { - var cache = PFont.PFontCache; - var idx = fontName + "/" + fontSize; - if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize); - return cache[idx] - }; - PFont.list = function() { - return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] - }; - PFont.preloading = { - template: {}, - initialized: false, - initialize: function() { - var generateTinyFont = function() { - var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; - var expand = function(input) { - return "AAAAAAAA".substr(~~input ? 7 - input : 6) - }; - return encoded.replace(/[#237]/g, expand) - }; - var fontface = document.createElement("style"); - fontface.setAttribute("type", "text/css"); - fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; - document.head.appendChild(fontface); - var element = document.createElement("span"); - element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.template = element; - this.initialized = true - }, - getElementWidth: function(element) { - return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") - }, - timeAttempted: 0, - pending: function(intervallength) { - if (!this.initialized) this.initialize(); - var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); - for (var i = 0; i < this.fontList.length; i++) { - element = this.fontList[i]; - computedWidthFont = this.getElementWidth(element); - if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { - this.timeAttempted += intervallength; - return true - } else { - document.body.removeChild(element); - this.fontList.splice(i--, 1); - this.timeAttempted = 0 - } - } - if (this.fontList.length === 0) return false; - return true - }, - fontList: [], - addedList: {}, - add: function(fontSrc) { - if (!this.initialized) this.initialize(); - var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, - fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; - if (this.addedList[fontName]) return; - var style = document.createElement("style"); - style.setAttribute("type", "text/css"); - style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; - document.head.appendChild(style); - this.addedList[fontName] = true; - var element = document.createElement("span"); - element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; - element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; - element.innerHTML = "AAAAAAAA"; - document.body.appendChild(element); - this.fontList.push(element) - } - }; - defaultScope.PFont = PFont; - var Processing = this.Processing = function(aCanvas, aCode) { - if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; - var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; - if (pgraphicsMode) curElement = document.createElement("canvas"); - else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; - if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; - - function unimplemented(s) { - Processing.debug("Unimplemented - " + s) - } - var p = this; - p.externals = { - canvas: curElement, - context: undef, - sketch: undef - }; - p.name = "Processing.js Instance"; - p.use3DContext = false; - p.focused = false; - p.breakShape = false; - p.glyphTable = {}; - p.pmouseX = 0; - p.pmouseY = 0; - p.mouseX = 0; - p.mouseY = 0; - p.mouseButton = 0; - p.mouseScroll = 0; - p.mouseClicked = undef; - p.mouseDragged = undef; - p.mouseMoved = undef; - p.mousePressed = undef; - p.mouseReleased = undef; - p.mouseScrolled = undef; - p.mouseOver = undef; - p.mouseOut = undef; - p.touchStart = undef; - p.touchEnd = undef; - p.touchMove = undef; - p.touchCancel = undef; - p.key = undef; - p.keyCode = undef; - p.keyPressed = nop; - p.keyReleased = nop; - p.keyTyped = nop; - p.draw = undef; - p.setup = undef; - p.__mousePressed = false; - p.__keyPressed = false; - p.__frameRate = 60; - p.frameCount = 0; - p.width = 100; - p.height = 100; - var curContext, curSketch, drawing, online = true, - doFill = true, - fillStyle = [1, 1, 1, 1], - currentFillColor = 4294967295, - isFillDirty = true, - doStroke = true, - strokeStyle = [0, 0, 0, 1], - currentStrokeColor = 4278190080, - isStrokeDirty = true, - lineWidth = 1, - loopStarted = false, - renderSmooth = false, - doLoop = true, - looping = 0, - curRectMode = 0, - curEllipseMode = 3, - normalX = 0, - normalY = 0, - normalZ = 0, - normalMode = 0, - curFrameRate = 60, - curMsPerFrame = 1E3 / curFrameRate, - curCursor = 'default', - oldCursor = curElement.style.cursor, - curShape = 20, - curShapeCount = 0, - curvePoints = [], - curTightness = 0, - curveDet = 20, - curveInited = false, - backgroundObj = -3355444, - bezDetail = 20, - colorModeA = 255, - colorModeX = 255, - colorModeY = 255, - colorModeZ = 255, - pathOpen = false, - mouseDragging = false, - pmouseXLastFrame = 0, - pmouseYLastFrame = 0, - curColorMode = 1, - curTint = null, - curTint3d = null, - getLoaded = false, - start = Date.now(), - timeSinceLastFPS = start, - framesSinceLastFPS = 0, - textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = { - attributes: {}, - locations: {} - }, - programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = { - width: 0, - height: 0 - }, - curTextureMode = 2, - usingTexture = false, - textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, - verticalTextAlignment = 0, - textMode = 4, - curFontName = "Arial", - curTextSize = 12, - curTextAscent = 9, - curTextDescent = 2, - curTextLeading = 14, - curTextFont = PFont.get(curFontName, curTextSize), - originalContext, proxyContext = null, - isContextReplaced = false, - setPixelsCached, maxPixelsCached = 1E3, - pressedKeysMap = [], - lastPressedKeyCode = null, - codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; - var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; - if (document.defaultView && document.defaultView.getComputedStyle) { - stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0; - stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0; - styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0; - styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0 - } - var lightCount = 0; - var sphereDetailV = 0, - sphereDetailU = 0, - sphereX = [], - sphereY = [], - sphereZ = [], - sinLUT = new Float32Array(720), - cosLUT = new Float32Array(720), - sphereVerts, sphereNorms; - var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, - frustumMode = false, - cameraFOV = 60 * (Math.PI / 180), - cameraX = p.width / 2, - cameraY = p.height / 2, - cameraZ = cameraY / Math.tan(cameraFOV / 2), - cameraNear = cameraZ / 10, - cameraFar = cameraZ * 10, - cameraAspect = p.width / p.height; - var vertArray = [], - curveVertArray = [], - curveVertCount = 0, - isCurve = false, - isBezier = false, - firstVert = true; - var curShapeMode = 0; - var styleArray = []; - var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, - -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]); - var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]); - var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]); - var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); - var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); - var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; - var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}"; - var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; - var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}"; - var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); - var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}"; - var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}"; - - function uniformf(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue); - else curContext.uniform1f(varLocation, varValue) - } - function uniformi(cacheId, programObj, varName, varValue) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue); - else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue); - else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue); - else curContext.uniform1i(varLocation, varValue) - } - function uniformMatrix(cacheId, programObj, varName, transpose, matrix) { - var varLocation = curContextCache.locations[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getUniformLocation(programObj, varName); - curContextCache.locations[cacheId] = varLocation - } - if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix); - else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix); - else curContext.uniformMatrix2fv(varLocation, transpose, matrix) - } - function vertexAttribPointer(cacheId, programObj, varName, size, VBO) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) { - curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO); - curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0); - curContext.enableVertexAttribArray(varLocation) - } - } - function disableVertexAttribPointer(cacheId, programObj, varName) { - var varLocation = curContextCache.attributes[cacheId]; - if (varLocation === undef) { - varLocation = curContext.getAttribLocation(programObj, varName); - curContextCache.attributes[cacheId] = varLocation - } - if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation) - } - var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) { - var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER); - curContext.shaderSource(vertexShaderObject, vetexShaderSource); - curContext.compileShader(vertexShaderObject); - if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject); - var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER); - curContext.shaderSource(fragmentShaderObject, fragmentShaderSource); - curContext.compileShader(fragmentShaderObject); - if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject); - var programObject = curContext.createProgram(); - curContext.attachShader(programObject, vertexShaderObject); - curContext.attachShader(programObject, fragmentShaderObject); - curContext.linkProgram(programObject); - if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders."; - return programObject - }; - var imageModeCorner = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: w, - h: h - } - }; - var imageModeConvert = imageModeCorner; - var imageModeCorners = function(x, y, w, h, whAreSizes) { - return { - x: x, - y: y, - w: whAreSizes ? w : w - x, - h: whAreSizes ? h : h - y - } - }; - var imageModeCenter = function(x, y, w, h, whAreSizes) { - return { - x: x - w / 2, - y: y - h / 2, - w: w, - h: h - } - }; - var DrawingShared = function() {}; - var Drawing2D = function() {}; - var Drawing3D = function() {}; - var DrawingPre = function() {}; - Drawing2D.prototype = new DrawingShared; - Drawing2D.prototype.constructor = Drawing2D; - Drawing3D.prototype = new DrawingShared; - Drawing3D.prototype.constructor = Drawing3D; - DrawingPre.prototype = new DrawingShared; - DrawingPre.prototype.constructor = DrawingPre; - DrawingShared.prototype.a3DOnlyFunction = nop; - var charMap = {}; - var Char = p.Character = function(chr) { - if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); - else if (typeof chr === "number") this.code = chr; - else if (chr instanceof Char) this.code = chr; - else this.code = NaN; - return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code] - }; - Char.prototype.toString = function() { - return String.fromCharCode(this.code) - }; - Char.prototype.valueOf = function() { - return this.code - }; - var PShape = p.PShape = function(family) { - this.family = family || 0; - this.visible = true; - this.style = true; - this.children = []; - this.nameTable = []; - this.params = []; - this.name = ""; - this.image = null; - this.matrix = null; - this.kind = null; - this.close = null; - this.width = null; - this.height = null; - this.parent = null - }; - PShape.prototype = { - isVisible: function() { - return this.visible - }, - setVisible: function(visible) { - this.visible = visible - }, - disableStyle: function() { - this.style = false; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() - }, - enableStyle: function() { - this.style = true; - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() - }, - getFamily: function() { - return this.family - }, - getWidth: function() { - return this.width - }, - getHeight: function() { - return this.height - }, - setName: function(name) { - this.name = name - }, - getName: function() { - return this.name - }, - draw: function() { - if (this.visible) { - this.pre(); - this.drawImpl(); - this.post() - } - }, - drawImpl: function() { - if (this.family === 0) this.drawGroup(); - else if (this.family === 1) this.drawPrimitive(); - else if (this.family === 3) this.drawGeometry(); - else if (this.family === 21) this.drawPath() - }, - drawPath: function() { - var i, j; - if (this.vertices.length === 0) return; - p.beginShape(); - if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]); - else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); - else { - var index = 0; - if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false; - index++ - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1]); - index++ - } else { - if (this.vertexCodes[i] === 3) p.breakShape = true - } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { - p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true; - else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false; - p.breakShape = false - } else if (this.vertexCodes[i] === 1) { - p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]); - index += 3 - } else if (this.vertexCodes[i] === 2) { - p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); - index++ - } else if (this.vertexCodes[i] === 3) p.breakShape = true - } - p.endShape(this.close ? 2 : 1) - }, - drawGeometry: function() { - var i, j; - p.beginShape(this.kind); - if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]); - else for (i = 0, j = this.vertices.length; i < j; i++) { - var vert = this.vertices[i]; - if (vert[2] === 0) p.vertex(vert[0], vert[1]); - else p.vertex(vert[0], vert[1], vert[2]) - } - p.endShape() - }, - drawGroup: function() { - for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw() - }, - drawPrimitive: function() { - if (this.kind === 2) p.point(this.params[0], this.params[1]); - else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]); - else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); - else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]); - else if (this.kind === 30) if (this.image !== null) { - p.imageMode(0); - p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]) - } else { - p.rectMode(0); - p.rect(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 31) { - p.ellipseMode(0); - p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]) - } else if (this.kind === 32) { - p.ellipseMode(0); - p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]) - } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]); - else p.box(this.params[0], this.params[1], this.params[2]); - else if (this.kind === 40) p.sphere(this.params[0]) - }, - pre: function() { - if (this.matrix) { - p.pushMatrix(); - curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5]) - } - if (this.style) { - p.pushStyle(); - this.styles() - } - }, - post: function() { - if (this.matrix) p.popMatrix(); - if (this.style) p.popStyle() - }, - styles: function() { - if (this.stroke) { - p.stroke(this.strokeColor); - p.strokeWeight(this.strokeWeight); - p.strokeCap(this.strokeCap); - p.strokeJoin(this.strokeJoin) - } else p.noStroke(); - if (this.fill) p.fill(this.fillColor); - else p.noFill() - }, - getChild: function(child) { - var i, j; - if (typeof child === "number") return this.children[child]; - var found; - if (child === "" || this.name === child) return this; - if (this.nameTable.length > 0) { - for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { - found = this.nameTable[i]; - break - } - if (found) return found - } - for (i = 0, j = this.children.length; i < j; i++) { - found = this.children[i].getChild(child); - if (found) return found - } - return null - }, - getChildCount: function() { - return this.children.length - }, - addChild: function(child) { - this.children.push(child); - child.parent = this; - if (child.getName() !== null) this.addName(child.getName(), child) - }, - addName: function(name, shape) { - if (this.parent !== null) this.parent.addName(name, shape); - else this.nameTable.push([name, shape]) - }, - translate: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.translate(arguments[0], arguments[1]) - } else { - this.checkMatrix(3); - this.matrix.translate(arguments[0], arguments[1], 0) - } - }, - checkMatrix: function(dimensions) { - if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D; - else this.matrix = new p.PMatrix3D; - else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D - }, - rotateX: function(angle) { - this.rotate(angle, 1, 0, 0) - }, - rotateY: function(angle) { - this.rotate(angle, 0, 1, 0) - }, - rotateZ: function(angle) { - this.rotate(angle, 0, 0, 1) - }, - rotate: function() { - if (arguments.length === 1) { - this.checkMatrix(2); - this.matrix.rotate(arguments[0]) - } else { - this.checkMatrix(3); - this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3]) - } - }, - scale: function() { - if (arguments.length === 2) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1]) - } else if (arguments.length === 3) { - this.checkMatrix(2); - this.matrix.scale(arguments[0], arguments[1], arguments[2]) - } else { - this.checkMatrix(2); - this.matrix.scale(arguments[0]) - } - }, - resetMatrix: function() { - this.checkMatrix(2); - this.matrix.reset() - }, - applyMatrix: function(matrix) { - if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1); - else if (arguments.length === 6) { - this.checkMatrix(2); - this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1) - } else if (arguments.length === 16) { - this.checkMatrix(3); - this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]) - } - } - }; - var PShapeSVG = p.PShapeSVG = function() { - p.PShape.call(this); - if (arguments.length === 1) { - this.element = arguments[0]; - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = null; - this.strokeGradientPaint = null; - this.strokeName = null; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillName = null; - this.fillOpacity = 1; - if (this.element.getName() !== "svg") throw "root is not , it's <" + this.element.getName() + ">"; - } else if (arguments.length === 2) if (typeof arguments[1] === "string") { - if (arguments[1].indexOf(".svg") > -1) { - this.element = new p.XMLElement(null, arguments[1]); - this.vertexCodes = []; - this.vertices = []; - this.opacity = 1; - this.stroke = false; - this.strokeColor = 4278190080; - this.strokeWeight = 1; - this.strokeCap = 'butt'; - this.strokeJoin = 'miter'; - this.strokeGradient = ""; - this.strokeGradientPaint = ""; - this.strokeName = ""; - this.strokeOpacity = 1; - this.fill = true; - this.fillColor = 4278190080; - this.fillGradient = null; - this.fillGradientPaint = null; - this.fillOpacity = 1 - } - } else if (arguments[0]) { - this.element = arguments[1]; - this.vertexCodes = arguments[0].vertexCodes.slice(); - this.vertices = arguments[0].vertices.slice(); - this.stroke = arguments[0].stroke; - this.strokeColor = arguments[0].strokeColor; - this.strokeWeight = arguments[0].strokeWeight; - this.strokeCap = arguments[0].strokeCap; - this.strokeJoin = arguments[0].strokeJoin; - this.strokeGradient = arguments[0].strokeGradient; - this.strokeGradientPaint = arguments[0].strokeGradientPaint; - this.strokeName = arguments[0].strokeName; - this.fill = arguments[0].fill; - this.fillColor = arguments[0].fillColor; - this.fillGradient = arguments[0].fillGradient; - this.fillGradientPaint = arguments[0].fillGradientPaint; - this.fillName = arguments[0].fillName; - this.strokeOpacity = arguments[0].strokeOpacity; - this.fillOpacity = arguments[0].fillOpacity; - this.opacity = arguments[0].opacity - } - this.name = this.element.getStringAttribute("id"); - var displayStr = this.element.getStringAttribute("display", "inline"); - this.visible = displayStr !== "none"; - var str = this.element.getAttribute("transform"); - if (str) this.matrix = this.parseMatrix(str); - var viewBoxStr = this.element.getStringAttribute("viewBox"); - if (viewBoxStr !== null) { - var viewBox = viewBoxStr.split(" "); - this.width = viewBox[2]; - this.height = viewBox[3] - } - var unitWidth = this.element.getStringAttribute("width"); - var unitHeight = this.element.getStringAttribute("height"); - if (unitWidth !== null) { - this.width = this.parseUnitSize(unitWidth); - this.height = this.parseUnitSize(unitHeight) - } else if (this.width === 0 || this.height === 0) { - this.width = 1; - this.height = 1; - throw "The width and/or height is not " + "readable in the tag of this file."; - } - this.parseColors(this.element); - this.parseChildren(this.element) - }; - PShapeSVG.prototype = new PShape; - PShapeSVG.prototype.parseMatrix = function() { - function getCoords(s) { - var m = []; - s.replace(/\((.*?)\)/, function() { - return function(all, params) { - m = params.replace(/,+/g, " ").split(/\s+/) - } - }()); - return m - } - return function(str) { - this.checkMatrix(2); - var pieces = []; - str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { - pieces.push(p.trim(all)) - }); - if (pieces.length === 0) return null; - for (var i = 0, j = pieces.length; i < j; i++) { - var m = getCoords(pieces[i]); - if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]); - else if (pieces[i].indexOf("translate") !== -1) { - var tx = m[0]; - var ty = m.length === 2 ? m[1] : 0; - this.matrix.translate(tx, ty) - } else if (pieces[i].indexOf("scale") !== -1) { - var sx = m[0]; - var sy = m.length === 2 ? m[1] : m[0]; - this.matrix.scale(sx, sy) - } else if (pieces[i].indexOf("rotate") !== -1) { - var angle = m[0]; - if (m.length === 1) this.matrix.rotate(p.radians(angle)); - else if (m.length === 3) { - this.matrix.translate(m[1], m[2]); - this.matrix.rotate(p.radians(m[0])); - this.matrix.translate(-m[1], -m[2]) - } - } else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0])); - else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]) - } - return this.matrix - } - }(); - PShapeSVG.prototype.parseChildren = function(element) { - var newelement = element.getChildren(); - var children = new p.PShape; - for (var i = 0, j = newelement.length; i < j; i++) { - var kid = this.parseChild(newelement[i]); - if (kid) children.addChild(kid) - } - this.children.push(children) - }; - PShapeSVG.prototype.getName = function() { - return this.name - }; - PShapeSVG.prototype.parseChild = function(elem) { - var name = elem.getName(); - var shape; - if (name === "g") shape = new PShapeSVG(this, elem); - else if (name === "defs") shape = new PShapeSVG(this, elem); - else if (name === "line") { - shape = new PShapeSVG(this, elem); - shape.parseLine() - } else if (name === "circle") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(true) - } else if (name === "ellipse") { - shape = new PShapeSVG(this, elem); - shape.parseEllipse(false) - } else if (name === "rect") { - shape = new PShapeSVG(this, elem); - shape.parseRect() - } else if (name === "polygon") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(true) - } else if (name === "polyline") { - shape = new PShapeSVG(this, elem); - shape.parsePoly(false) - } else if (name === "path") { - shape = new PShapeSVG(this, elem); - shape.parsePath() - } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); - else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); - else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); - else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); - else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); - else nop(); - return shape - }; - PShapeSVG.prototype.parsePath = function() { - this.family = 21; - this.kind = 0; - var pathDataChars = []; - var c; - var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); - if (pathData === null) return; - pathData = p.__toCharArray(pathData); - var cx = 0, - cy = 0, - ctrlX = 0, - ctrlY = 0, - ctrlX1 = 0, - ctrlX2 = 0, - ctrlY1 = 0, - ctrlY2 = 0, - endX = 0, - endY = 0, - ppx = 0, - ppy = 0, - px = 0, - py = 0, - i = 0, - valOf = 0; - var str = ""; - var tmpArray = []; - var flag = false; - var lastInstruction; - var command; - var j, k; - while (i < pathData.length) { - valOf = pathData[i].valueOf(); - if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) { - j = i; - i++; - if (i < pathData.length) { - tmpArray = []; - valOf = pathData[i].valueOf(); - while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) { - if (valOf === 32) { - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - i++ - } else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) { - str += pathData[i].toString(); - i++ - } else { - if (str !== "") tmpArray.push(parseFloat(str)); - str = pathData[i].toString(); - i++ - } else { - str += pathData[i].toString(); - i++ - } - if (i === pathData.length) flag = true; - else valOf = pathData[i].valueOf() - } - } - if (str !== "") { - tmpArray.push(parseFloat(str)); - str = "" - } - command = pathData[j]; - valOf = command.valueOf(); - if (valOf === 77) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx = tmpArray[0]; - cy = tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 109) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) { - cx += tmpArray[0]; - cy += tmpArray[1]; - this.parsePathMoveto(cx, cy); - if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } - } else if (valOf === 76) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx = tmpArray[j]; - cy = tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 108) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - cx += tmpArray[j]; - cy += tmpArray[j + 1]; - this.parsePathLineto(cx, cy) - } - } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { - cx = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { - cx += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { - cy = tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { - cy += tmpArray[j]; - this.parsePathLineto(cx, cy) - } else if (valOf === 67) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = tmpArray[j]; - ctrlY1 = tmpArray[j + 1]; - ctrlX2 = tmpArray[j + 2]; - ctrlY2 = tmpArray[j + 3]; - endX = tmpArray[j + 4]; - endY = tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 99) { - if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) { - ctrlX1 = cx + tmpArray[j]; - ctrlY1 = cy + tmpArray[j + 1]; - ctrlX2 = cx + tmpArray[j + 2]; - ctrlY2 = cy + tmpArray[j + 3]; - endX = cx + tmpArray[j + 4]; - endY = cy + tmpArray[j + 5]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 83) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = tmpArray[j]; - ctrlY2 = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 115) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX1 = px + (px - ppx); - ctrlY1 = py + (py - ppy) - } else { - ctrlX1 = this.vertices[this.vertices.length - 1][0]; - ctrlY1 = this.vertices[this.vertices.length - 1][1] - } - ctrlX2 = cx + tmpArray[j]; - ctrlY2 = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 81) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = tmpArray[j]; - ctrlY = tmpArray[j + 1]; - endX = tmpArray[j + 2]; - endY = tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 113) { - if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) { - ctrlX = cx + tmpArray[j]; - ctrlY = cy + tmpArray[j + 1]; - endX = cx + tmpArray[j + 2]; - endY = cy + tmpArray[j + 3]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 84) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = tmpArray[j]; - endY = tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 116) { - if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { - if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") { - ppx = this.vertices[this.vertices.length - 2][0]; - ppy = this.vertices[this.vertices.length - 2][1]; - px = this.vertices[this.vertices.length - 1][0]; - py = this.vertices[this.vertices.length - 1][1]; - ctrlX = px + (px - ppx); - ctrlY = py + (py - ppy) - } else { - ctrlX = cx; - ctrlY = cy - } - endX = cx + tmpArray[j]; - endY = cy + tmpArray[j + 1]; - this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY); - cx = endX; - cy = endY - } - } else if (valOf === 90 || valOf === 122) this.close = true; - lastInstruction = command.toString() - } else i++ - } - }; - PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3); - this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3); - this.parsePathVertex(x2, y2) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { - if (this.vertices.length > 0) { - this.parsePathCode(1); - this.parsePathVertex(x1, y1); - this.parsePathVertex(x2, y2); - this.parsePathVertex(x3, y3) - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathLineto = function(px, py) { - if (this.vertices.length > 0) { - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = false - } else throw "Path must start with M/m"; - }; - PShapeSVG.prototype.parsePathMoveto = function(px, py) { - if (this.vertices.length > 0) this.parsePathCode(3); - this.parsePathCode(0); - this.parsePathVertex(px, py); - this.vertices[this.vertices.length - 1]["moveTo"] = true - }; - PShapeSVG.prototype.parsePathVertex = function(x, y) { - var verts = []; - verts[0] = x; - verts[1] = y; - this.vertices.push(verts) - }; - PShapeSVG.prototype.parsePathCode = function(what) { - this.vertexCodes.push(what) - }; - PShapeSVG.prototype.parsePoly = function(val) { - this.family = 21; - this.close = val; - var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " ")); - if (pointsAttr !== null) { - var pointsBuffer = pointsAttr.split(" "); - if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) { - var verts = []; - verts[0] = pointsBuffer[i]; - verts[1] = pointsBuffer[++i]; - this.vertices.push(verts) - } else throw "Error parsing polygon points: odd number of coordinates provided"; - } - }; - PShapeSVG.prototype.parseRect = function() { - this.kind = 30; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x"); - this.params[1] = this.element.getFloatAttribute("y"); - this.params[2] = this.element.getFloatAttribute("width"); - this.params[3] = this.element.getFloatAttribute("height"); - if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing "; - }; - PShapeSVG.prototype.parseEllipse = function(val) { - this.kind = 31; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("cx") | 0; - this.params[1] = this.element.getFloatAttribute("cy") | 0; - var rx, ry; - if (val) { - rx = ry = this.element.getFloatAttribute("r"); - if (rx < 0) throw "svg error: negative radius found while parsing "; - } else { - rx = this.element.getFloatAttribute("rx"); - ry = this.element.getFloatAttribute("ry"); - if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing "; - } - this.params[0] -= rx; - this.params[1] -= ry; - this.params[2] = rx * 2; - this.params[3] = ry * 2 - }; - PShapeSVG.prototype.parseLine = function() { - this.kind = 4; - this.family = 1; - this.params = []; - this.params[0] = this.element.getFloatAttribute("x1"); - this.params[1] = this.element.getFloatAttribute("y1"); - this.params[2] = this.element.getFloatAttribute("x2"); - this.params[3] = this.element.getFloatAttribute("y2") - }; - PShapeSVG.prototype.parseColors = function(element) { - if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity")); - if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke")); - if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width")); - if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin")); - if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap")); - if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill")); - if (element.hasAttribute("style")) { - var styleText = element.getStringAttribute("style"); - var styleTokens = styleText.toString().split(";"); - for (var i = 0, j = styleTokens.length; i < j; i++) { - var tokens = p.trim(styleTokens[i].split(":")); - if (tokens[0] === "fill") this.setFill(tokens[1]); - else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); - else if (tokens[0] === "stroke") this.setStroke(tokens[1]); - else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); - else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); - else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); - else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); - else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) - } - } - }; - PShapeSVG.prototype.setFillOpacity = function(opacityText) { - this.fillOpacity = parseFloat(opacityText); - this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setFill = function(fillText) { - var opacityMask = this.fillColor & 4278190080; - if (fillText === "none") this.fill = false; - else if (fillText.indexOf("#") === 0) { - this.fill = true; - if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 16777215 - } else if (fillText.indexOf("rgb") === 0) { - this.fill = true; - this.fillColor = opacityMask | this.parseRGB(fillText) - } else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1); - else if (colors[fillText]) { - this.fill = true; - this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setOpacity = function(opacity) { - this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; - this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 - }; - PShapeSVG.prototype.setStroke = function(strokeText) { - var opacityMask = this.strokeColor & 4278190080; - if (strokeText === "none") this.stroke = false; - else if (strokeText.charAt(0) === "#") { - this.stroke = true; - if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3"); - this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 16777215 - } else if (strokeText.indexOf("rgb") === 0) { - this.stroke = true; - this.strokeColor = opacityMask | this.parseRGB(strokeText) - } else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1); - else if (colors[strokeText]) { - this.stroke = true; - this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 16777215 - } - }; - PShapeSVG.prototype.setStrokeWeight = function(weight) { - this.strokeWeight = this.parseUnitSize(weight) - }; - PShapeSVG.prototype.setStrokeJoin = function(linejoin) { - if (linejoin === "miter") this.strokeJoin = 'miter'; - else if (linejoin === "round") this.strokeJoin = 'round'; - else if (linejoin === "bevel") this.strokeJoin = 'bevel' - }; - PShapeSVG.prototype.setStrokeCap = function(linecap) { - if (linecap === "butt") this.strokeCap = 'butt'; - else if (linecap === "round") this.strokeCap = 'round'; - else if (linecap === "square") this.strokeCap = 'square' - }; - PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { - this.strokeOpacity = parseFloat(opacityText); - this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 - }; - PShapeSVG.prototype.parseRGB = function(color) { - var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")")); - var values = sub.split(", "); - return values[0] << 16 | values[1] << 8 | values[2] - }; - PShapeSVG.prototype.parseUnitSize = function(text) { - var len = text.length - 2; - if (len < 0) return text; - if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25; - if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; - if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; - if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; - if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; - if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); - return parseFloat(text) - }; - p.shape = function(shape, x, y, width, height) { - if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) { - p.pushMatrix(); - if (curShapeMode === 3) if (arguments.length === 5) { - p.translate(x - width / 2, y - height / 2); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2); - else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2); - else if (curShapeMode === 0) if (arguments.length === 5) { - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else { - if (arguments.length === 3) p.translate(x, y) - } else if (curShapeMode === 1) if (arguments.length === 5) { - width -= x; - height -= y; - p.translate(x, y); - p.scale(width / shape.getWidth(), height / shape.getHeight()) - } else if (arguments.length === 3) p.translate(x, y); - shape.draw(); - if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix() - } - }; - p.shapeMode = function(mode) { - curShapeMode = mode - }; - p.loadShape = function(filename) { - if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename); - return null - }; - var XMLAttribute = function(fname, n, nameSpace, v, t) { - this.fullName = fname || ""; - this.name = n || ""; - this.namespace = nameSpace || ""; - this.value = v; - this.type = t - }; - XMLAttribute.prototype = { - getName: function() { - return this.name - }, - getFullName: function() { - return this.fullName - }, - getNamespace: function() { - return this.namespace - }, - getValue: function() { - return this.value - }, - getType: function() { - return this.type - }, - setValue: function(newval) { - this.value = newval - } - }; - var XMLElement = p.XMLElement = function() { - this.attributes = []; - this.children = []; - this.fullName = null; - this.name = null; - this.namespace = ""; - this.content = null; - this.parent = null; - this.lineNr = ""; - this.systemID = ""; - this.type = "ELEMENT"; - if (arguments.length === 4) { - this.fullName = arguments[0] || ""; - if (arguments[1]) this.name = arguments[1]; - else { - var index = this.fullName.indexOf(":"); - if (index >= 0) this.name = this.fullName.substring(index + 1); - else this.name = this.fullName - } - this.namespace = arguments[1]; - this.lineNr = arguments[3]; - this.systemID = arguments[2] - } else if (arguments.length === 2 && arguments[1].indexOf(".") > -1) this.parse(arguments[arguments.length - 1]); - else if (arguments.length === 1 && typeof arguments[0] === "string") this.parse(arguments[0]) - }; - XMLElement.prototype = { - parse: function(textstring) { - var xmlDoc; - try { - var extension = textstring.substring(textstring.length - 4); - if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); - xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); - var elements = xmlDoc.documentElement; - if (elements) this.parseChildrenRecursive(null, elements); - else throw "Error loading document"; - return this - } catch(e) { - throw e; - } - }, - parseChildrenRecursive: function(parent, elementpath) { - var xmlelement, xmlattribute, tmpattrib, l, m, child; - if (!parent) { - this.fullName = elementpath.localName; - this.name = elementpath.nodeName; - xmlelement = this - } else { - xmlelement = new XMLElement(elementpath.localName, elementpath.nodeName, "", ""); - xmlelement.parent = parent - } - if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); - for (l = 0, m = elementpath.attributes.length; l < m; l++) { - tmpattrib = elementpath.attributes[l]; - xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); - xmlelement.attributes.push(xmlattribute) - } - for (l = 0, m = elementpath.childNodes.length; l < m; l++) { - var node = elementpath.childNodes[l]; - if (node.nodeType === 1 || node.nodeType === 3) { - child = xmlelement.parseChildrenRecursive(xmlelement, node); - if (child !== null) xmlelement.children.push(child) - } - } - return xmlelement - }, - createElement: function() { - if (arguments.length === 2) return new XMLElement(arguments[0], arguments[1], null, null); - return new XMLElement(arguments[0], arguments[1], arguments[2], arguments[3]) - }, - createPCDataElement: function(content) { - if (content.replace(/^\s+$/g, "") === "") return null; - var pcdata = new XMLElement; - pcdata.content = content; - pcdata.type = "TEXT"; - return pcdata - }, - hasAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null - }, - equals: function(other) { - if (! (other instanceof XMLElement)) return false; - var i, j; - if (this.name !== other.getLocalName()) return false; - if (this.attributes.length !== other.getAttributeCount()) return false; - if (this.attributes.length !== other.attributes.length) return false; - var attr_name, attr_ns, attr_value, attr_type, attr_other; - for (i = 0, j = this.attributes.length; i < j; i++) { - attr_name = this.attributes[i].getName(); - attr_ns = this.attributes[i].getNamespace(); - attr_other = other.findAttribute(attr_name, attr_ns); - if (attr_other === null) return false; - if (this.attributes[i].getValue() !== attr_other.getValue()) return false; - if (this.attributes[i].getType() !== attr_other.getType()) return false - } - if (this.children.length !== other.getChildCount()) return false; - if (this.children.length > 0) { - var child1, child2; - for (i = 0, j = this.children.length; i < j; i++) { - child1 = this.getChild(i); - child2 = other.getChild(i); - if (!child1.equals(child2)) return false - } - return true - } - return this.content === other.content - }, - getContent: function() { - if (this.type === "TEXT") return this.content; - var children = this.children; - if (children.length === 1 && children[0].type === "TEXT") return children[0].content; - return null - }, - getAttribute: function() { - var attribute; - if (arguments.length === 2) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return arguments[1] - } else if (arguments.length === 1) { - attribute = this.findAttribute(arguments[0]); - if (attribute) return attribute.getValue(); - return null - } else if (arguments.length === 3) { - attribute = this.findAttribute(arguments[0], arguments[1]); - if (attribute) return attribute.getValue(); - return arguments[2] - } - }, - getStringAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0]); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getString: function(attributeName) { - return this.getStringAttribute(attributeName) - }, - getFloatAttribute: function() { - if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getFloat: function(attributeName) { - return this.getFloatAttribute(attributeName) - }, - getIntAttribute: function() { - if (arguments.length === 1) return this.getAttribute(arguments[0], 0); - if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); - return this.getAttribute(arguments[0], arguments[1], arguments[2]) - }, - getInt: function(attributeName) { - return this.getIntAttribute(attributeName) - }, - hasChildren: function() { - return this.children.length > 0 - }, - addChild: function(child) { - if (child !== null) { - child.parent = this; - this.children.push(child) - } - }, - insertChild: function(child, index) { - if (child) { - if (child.getLocalName() === null && !this.hasChildren()) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild.getLocalName() === null) { - lastChild.setContent(lastChild.getContent() + child.getContent()); - return - } - } - child.parent = this; - this.children.splice(index, 0, child) - } - }, - getChild: function() { - if (typeof arguments[0] === "number") return this.children[arguments[0]]; - if (arguments[0].indexOf("/") !== -1) { - this.getChildRecursive(arguments[0].split("/"), 0); - return null - } - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) return kid - } - return null - }, - getChildren: function() { - if (arguments.length === 1) { - if (typeof arguments[0] === "number") return this.getChild(arguments[0]); - if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); - var matches = []; - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === arguments[0]) matches.push(kid) - } - return matches - } - return this.children - }, - getChildCount: function() { - return this.children.length - }, - getChildRecursive: function(items, offset) { - var kid, kidName; - for (var i = 0, j = this.getChildCount(); i < j; i++) { - kid = this.getChild(i); - kidName = kid.getName(); - if (kidName !== null && kidName === items[offset]) { - if (offset === items.length - 1) return kid; - offset += 1; - return kid.getChildRecursive(items, offset) - } - } - return null - }, - getChildrenRecursive: function(items, offset) { - if (offset === items.length - 1) return this.getChildren(items[offset]); - var matches = this.getChildren(items[offset]); - var kidMatches = []; - for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); - return kidMatches - }, - isLeaf: function() { - return !this.hasChildren() - }, - listChildren: function() { - var arr = []; - for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); - return arr - }, - removeAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { - this.attributes.splice(i, 1); - break - } - }, - removeChild: function(child) { - if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { - this.children.splice(i, 1); - break - } - }, - removeChildAtIndex: function(index) { - if (this.children.length > index) this.children.splice(index, 1) - }, - findAttribute: function(name, namespace) { - this.namespace = namespace || ""; - for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; - return null - }, - setAttribute: function() { - var attr; - if (arguments.length === 3) { - var index = arguments[0].indexOf(":"); - var name = arguments[0].substring(index + 1); - attr = this.findAttribute(name, arguments[1]); - if (attr) attr.setValue(arguments[2]); - else { - attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA"); - this.attributes.push(attr) - } - } else { - attr = this.findAttribute(arguments[0]); - if (attr) attr.setValue(arguments[1]); - else { - attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA"); - this.attributes.push(attr) - } - } - }, - setString: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setInt: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setFloat: function(attribute, value) { - this.setAttribute(attribute, value) - }, - setContent: function(content) { - if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); - this.content = content - }, - setName: function() { - if (arguments.length === 1) { - this.name = arguments[0]; - this.fullName = arguments[0]; - this.namespace = null - } else { - var index = arguments[0].indexOf(":"); - if (arguments[1] === null || index < 0) this.name = arguments[0]; - else this.name = arguments[0].substring(index + 1); - this.fullName = arguments[0]; - this.namespace = arguments[1] - } - }, - getName: function() { - return this.fullName - }, - getLocalName: function() { - return this.name - }, - getAttributeCount: function() { - return this.attributes.length - }, - toString: function() { - if (this.type === "TEXT") return this.content; - var tagstring = (this.namespace !== "" && this.namespace !== this.name ? this.namespace + ":" : "") + this.name; - var xmlstring = "<" + tagstring; - var a, c; - for (a = 0; a < this.attributes.length; a++) { - var attr = this.attributes[a]; - xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' - } - if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; - else xmlstring += ">" + this.content + ""; - else { - xmlstring += ">"; - for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); - xmlstring += "" - } - return xmlstring - } - }; - XMLElement.parse = function(xmlstring) { - var element = new XMLElement; - element.parse(xmlstring); - return element - }; - var printMatrixHelper = function(elements) { - var big = 0; - for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i])); - else big = Math.abs(elements[i]); - var digits = (big + "").indexOf("."); - if (digits === 0) digits = 1; - else if (digits === -1) digits = (big + "").length; - return digits - }; - var PMatrix2D = p.PMatrix2D = function() { - if (arguments.length === 0) this.reset(); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array()); - else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - PMatrix2D.prototype = { - set: function() { - if (arguments.length === 6) { - var a = arguments; - this.set([a[0], a[1], a[2], a[3], a[4], a[5]]) - } else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix2D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.set([1, 0, 0, 0, 1, 0]) - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty) { - this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2]; - this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5] - }, - invTranslate: function(tx, ty) { - this.translate(-tx, -ty) - }, - transpose: function() {}, - mult: function(source, target) { - var x, y; - if (source instanceof - PVector) { - x = source.x; - y = source.y; - if (!target) target = new PVector - } else if (source instanceof Array) { - x = source[0]; - y = source[1]; - if (!target) target = [] - } - if (target instanceof Array) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5] - } else if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2]; - target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5]; - target.z = 0 - } - return target - }, - multX: function(x, y) { - return x * this.elements[0] + y * this.elements[1] + this.elements[2] - }, - multY: function(x, y) { - return x * this.elements[3] + y * this.elements[4] + this.elements[5] - }, - skewX: function(angle) { - this.apply(1, 0, 1, angle, 0, 0) - }, - skewY: function(angle) { - this.apply(1, 0, 1, 0, angle, 0) - }, - determinant: function() { - return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3] - }, - invert: function() { - var d = this.determinant(); - if (Math.abs(d) > -2147483648) { - var old00 = this.elements[0]; - var old01 = this.elements[1]; - var old02 = this.elements[2]; - var old10 = this.elements[3]; - var old11 = this.elements[4]; - var old12 = this.elements[5]; - this.elements[0] = old11 / d; - this.elements[3] = -old10 / d; - this.elements[1] = -old01 / d; - this.elements[4] = old00 / d; - this.elements[2] = (old01 * old12 - old11 * old02) / d; - this.elements[5] = (old10 * old02 - old00 * old12) / d; - return true - } - return false - }, - scale: function(sx, sy) { - if (sx && !sy) sy = sx; - if (sx && sy) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[3] *= sx; - this.elements[4] *= sy - } - }, - invScale: function(sx, sy) { - if (sx && !sy) sy = sx; - this.scale(1 / sx, 1 / sy) - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, this.elements[2], 0, 0, this.elements[5]]; - var e = 0; - for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3]; - this.elements = result.slice() - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array(); - else if (arguments.length === 6) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, source[2], 0, 0, source[5]]; - result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1]; - result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4]; - result[0] = this.elements[0] * source[0] + this.elements[3] * source[1]; - result[3] = this.elements[0] * source[3] + this.elements[3] * source[4]; - result[1] = this.elements[1] * source[0] + this.elements[4] * source[1]; - result[4] = this.elements[1] * source[3] + this.elements[4] * source[4]; - this.elements = result.slice() - }, - rotate: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - var temp1 = this.elements[0]; - var temp2 = this.elements[1]; - this.elements[0] = c * temp1 + s * temp2; - this.elements[1] = -s * temp1 + c * temp2; - temp1 = this.elements[3]; - temp2 = this.elements[4]; - this.elements[3] = c * temp1 + s * temp2; - this.elements[4] = -s * temp1 + c * temp2 - }, - rotateZ: function(angle) { - this.rotate(angle) - }, - invRotateZ: function(angle) { - this.rotateZ(angle - Math.PI) - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n"; - p.println(output) - } - }; - var PMatrix3D = p.PMatrix3D = function() { - this.reset() - }; - PMatrix3D.prototype = { - set: function() { - if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array(); - else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice() - }, - get: function() { - var outgoing = new PMatrix3D; - outgoing.set(this.elements); - return outgoing - }, - reset: function() { - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - }, - array: function array() { - return this.elements.slice() - }, - translate: function(tx, ty, tz) { - if (tz === undef) tz = 0; - this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2]; - this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6]; - this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10]; - this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14] - }, - transpose: function() { - var temp = this.elements[4]; - this.elements[4] = this.elements[1]; - this.elements[1] = temp; - temp = this.elements[8]; - this.elements[8] = this.elements[2]; - this.elements[2] = temp; - temp = this.elements[6]; - this.elements[6] = this.elements[9]; - this.elements[9] = temp; - temp = this.elements[3]; - this.elements[3] = this.elements[12]; - this.elements[12] = temp; - temp = this.elements[7]; - this.elements[7] = this.elements[13]; - this.elements[13] = temp; - temp = this.elements[11]; - this.elements[11] = this.elements[14]; - this.elements[14] = temp - }, - mult: function(source, target) { - var x, y, z, w; - if (source instanceof PVector) { - x = source.x; - y = source.y; - z = source.z; - w = 1; - if (!target) target = new PVector - } else if (source instanceof - Array) { - x = source[0]; - y = source[1]; - z = source[2]; - w = source[3] || 1; - if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0] - } - if (target instanceof Array) if (target.length === 3) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } else if (target.length === 4) { - target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w; - target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w; - target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w; - target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - } - if (target instanceof PVector) { - target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] - } - return target - }, - preApply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3]; - this.elements = result.slice() - }, - apply: function() { - var source; - if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array(); - else if (arguments.length === 16) source = Array.prototype.slice.call(arguments); - else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0]; - var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var e = 0; - for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12]; - this.elements = result.slice() - }, - rotate: function(angle, v0, v1, v2) { - if (!v1) this.rotateZ(angle); - else { - var c = p.cos(angle); - var s = p.sin(angle); - var t = 1 - c; - this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1) - } - }, - invApply: function() { - if (inverseCopy === undef) inverseCopy = new PMatrix3D; - var a = arguments; - inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - if (!inverseCopy.invert()) return false; - this.preApply(inverseCopy); - return true - }, - rotateX: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1]) - }, - rotateY: function(angle) { - var c = p.cos(angle); - var s = p.sin(angle); - this.apply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - rotateZ: function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.apply([c, - -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - scale: function(sx, sy, sz) { - if (sx && !sy && !sz) sy = sz = sx; - else if (sx && sy && !sz) sz = 1; - if (sx && sy && sz) { - this.elements[0] *= sx; - this.elements[1] *= sy; - this.elements[2] *= sz; - this.elements[4] *= sx; - this.elements[5] *= sy; - this.elements[6] *= sz; - this.elements[8] *= sx; - this.elements[9] *= sy; - this.elements[10] *= sz; - this.elements[12] *= sx; - this.elements[13] *= sy; - this.elements[14] *= sz - } - }, - skewX: function(angle) { - var t = Math.tan(angle); - this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - skewY: function(angle) { - var t = Math.tan(angle); - this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - }, - multX: function(x, y, z, w) { - if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3]; - if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; - return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w - }, - multY: function(x, y, z, w) { - if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7]; - if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; - return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w - }, - multZ: function(x, y, z, w) { - if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]; - return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w - }, - multW: function(x, y, z, w) { - if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15]; - return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w - }, - invert: function() { - var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4]; - var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4]; - var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4]; - var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5]; - var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5]; - var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6]; - var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12]; - var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12]; - var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12]; - var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13]; - var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13]; - var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14]; - var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - if (Math.abs(fDet) <= 1.0E-9) return false; - var kInv = []; - kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3; - kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1; - kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0; - kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0; - kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3; - kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1; - kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0; - kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0; - kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3; - kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1; - kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0; - kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0; - kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3; - kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1; - kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0; - kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0; - var fInvDet = 1 / fDet; - kInv[0] *= fInvDet; - kInv[1] *= fInvDet; - kInv[2] *= fInvDet; - kInv[3] *= fInvDet; - kInv[4] *= fInvDet; - kInv[5] *= fInvDet; - kInv[6] *= fInvDet; - kInv[7] *= fInvDet; - kInv[8] *= fInvDet; - kInv[9] *= fInvDet; - kInv[10] *= fInvDet; - kInv[11] *= fInvDet; - kInv[12] *= fInvDet; - kInv[13] *= fInvDet; - kInv[14] *= fInvDet; - kInv[15] *= fInvDet; - this.elements = kInv.slice(); - return true - }, - toString: function() { - var str = ""; - for (var i = 0; i < 15; i++) str += this.elements[i] + ", "; - str += this.elements[15]; - return str - }, - print: function() { - var digits = printMatrixHelper(this.elements); - var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n"; - p.println(output) - }, - invTranslate: function(tx, ty, tz) { - this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1) - }, - invRotateX: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, - 0, 0, 0, 1]) - }, - invRotateY: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1]) - }, - invRotateZ: function(angle) { - var c = Math.cos(-angle); - var s = Math.sin(-angle); - this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) - }, - invScale: function(x, y, z) { - this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1]) - } - }; - var PMatrixStack = p.PMatrixStack = function() { - this.matrixStack = [] - }; - PMatrixStack.prototype.load = function() { - var tmpMatrix = drawing.$newPMatrix(); - if (arguments.length === 1) tmpMatrix.set(arguments[0]); - else tmpMatrix.set(arguments); - this.matrixStack.push(tmpMatrix) - }; - Drawing2D.prototype.$newPMatrix = function() { - return new PMatrix2D - }; - Drawing3D.prototype.$newPMatrix = function() { - return new PMatrix3D - }; - PMatrixStack.prototype.push = function() { - this.matrixStack.push(this.peek()) - }; - PMatrixStack.prototype.pop = function() { - return this.matrixStack.pop() - }; - PMatrixStack.prototype.peek = function() { - var tmpMatrix = drawing.$newPMatrix(); - tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); - return tmpMatrix - }; - PMatrixStack.prototype.mult = function(matrix) { - this.matrixStack[this.matrixStack.length - 1].apply(matrix) - }; - p.split = function(str, delim) { - return str.split(delim) - }; - p.splitTokens = function(str, tokens) { - if (arguments.length === 1) tokens = "\n\t\r\u000c "; - tokens = "[" + tokens + "]"; - var ary = []; - var index = 0; - var pos = str.search(tokens); - while (pos >= 0) { - if (pos === 0) str = str.substring(1); - else { - ary[index] = str.substring(0, pos); - index++; - str = str.substring(pos) - } - pos = str.search(tokens) - } - if (str.length > 0) ary[index] = str; - if (ary.length === 0) ary = undef; - return ary - }; - p.append = function(array, element) { - array[array.length] = element; - return array - }; - p.concat = function(array1, array2) { - return array1.concat(array2) - }; - p.sort = function(array, numElem) { - var ret = []; - if (array.length > 0) { - var elemsToCopy = numElem > 0 ? numElem : array.length; - for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]); - if (typeof array[0] === "string") ret.sort(); - else ret.sort(function(a, b) { - return a - b - }); - if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j]) - } - return ret - }; - p.splice = function(array, value, index) { - if (value.length === 0) return array; - if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]); - else array.splice(index, 0, value); - return array - }; - p.subset = function(array, offset, length) { - var end = length !== undef ? offset + length : array.length; - return array.slice(offset, end) - }; - p.join = function(array, seperator) { - return array.join(seperator) - }; - p.shorten = function(ary) { - var newary = []; - var len = ary.length; - for (var i = 0; i < len; i++) newary[i] = ary[i]; - newary.pop(); - return newary - }; - p.expand = function(ary, targetSize) { - var temp = ary.slice(0), - newSize = targetSize || ary.length * 2; - temp.length = newSize; - return temp - }; - p.arrayCopy = function() { - var src, srcPos = 0, - dest, destPos = 0, - length; - if (arguments.length === 2) { - src = arguments[0]; - dest = arguments[1]; - length = src.length - } else if (arguments.length === 3) { - src = arguments[0]; - dest = arguments[1]; - length = arguments[2] - } else if (arguments.length === 5) { - src = arguments[0]; - srcPos = arguments[1]; - dest = arguments[2]; - destPos = arguments[3]; - length = arguments[4] - } - for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i]; - else throw "array index out of bounds exception"; - }; - p.reverse = function(array) { - return array.reverse() - }; - p.mix = function(a, b, f) { - return a + ((b - a) * f >> 8) - }; - p.peg = function(n) { - return n < 0 ? 0 : n > 255 ? 255 : n - }; - p.modes = function() { - var ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - min = Math.min, - max = Math.max; - - function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { - var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; - var r = ar + ((cr - ar) * f >> 8); - r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; - var g = ag + ((cg - ag) * f >> 8); - g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; - var b = ab + ((cb - ab) * f >> 8); - b = b < 0 ? 0 : b > 255 ? 255 : b; - return a | r | g | b - } - return { - replace: function(c1, c2) { - return c2 - }, - blend: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = c2 & RED_MASK, - bg = c2 & GREEN_MASK, - bb = c2 & BLUE_MASK; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - add: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) - }, - subtract: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) - }, - lightest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24; - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) - }, - darkest: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = c1 & RED_MASK, - ag = c1 & GREEN_MASK, - ab = c1 & BLUE_MASK, - br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), - bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), - bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); - return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK - }, - difference: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar > br ? ar - br : br - ar, - cg = ag > bg ? ag - bg : bg - ag, - cb = ab > bb ? ab - bb : bb - ab; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - exclusion: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar + br - (ar * br >> 7), - cg = ag + bg - (ag * bg >> 7), - cb = ab + bb - (ab * bb >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - multiply: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar * br >> 8, - cg = ag * bg >> 8, - cb = ab * bb >> 8; - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - screen: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = 255 - ((255 - ar) * (255 - br) >> 8), - cg = 255 - ((255 - ag) * (255 - bg) >> 8), - cb = 255 - ((255 - ab) * (255 - bb) >> 8); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - hard_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - soft_light: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), - cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), - cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - overlay: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK, - cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), - cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), - cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - dodge: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 255; - if (br !== 255) { - cr = (ar << 8) / (255 - br); - cr = cr < 0 ? 0 : cr > 255 ? 255 : cr - } - var cg = 255; - if (bg !== 255) { - cg = (ag << 8) / (255 - bg); - cg = cg < 0 ? 0 : cg > 255 ? 255 : cg - } - var cb = 255; - if (bb !== 255) { - cb = (ab << 8) / (255 - bb); - cb = cb < 0 ? 0 : cb > 255 ? 255 : cb - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - }, - burn: function(c1, c2) { - var f = (c2 & ALPHA_MASK) >>> 24, - ar = (c1 & RED_MASK) >> 16, - ag = (c1 & GREEN_MASK) >> 8, - ab = c1 & BLUE_MASK, - br = (c2 & RED_MASK) >> 16, - bg = (c2 & GREEN_MASK) >> 8, - bb = c2 & BLUE_MASK; - var cr = 0; - if (br !== 0) { - cr = (255 - ar << 8) / br; - cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) - } - var cg = 0; - if (bg !== 0) { - cg = (255 - ag << 8) / bg; - cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) - } - var cb = 0; - if (bb !== 0) { - cb = (255 - ab << 8) / bb; - cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) - } - return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) - } - } - }(); - - function color$4(aValue1, aValue2, aValue3, aValue4) { - var r, g, b, a; - if (curColorMode === 3) { - var rgb = p.color.toRGB(aValue1, aValue2, aValue3); - r = rgb[0]; - g = rgb[1]; - b = rgb[2] - } else { - r = Math.round(255 * (aValue1 / colorModeX)); - g = Math.round(255 * (aValue2 / colorModeY)); - b = Math.round(255 * (aValue3 / colorModeZ)) - } - a = Math.round(255 * (aValue4 / colorModeA)); - r = r < 0 ? 0 : r; - g = g < 0 ? 0 : g; - b = b < 0 ? 0 : b; - a = a < 0 ? 0 : a; - r = r > 255 ? 255 : r; - g = g > 255 ? 255 : g; - b = b > 255 ? 255 : b; - a = a > 255 ? 255 : a; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - } - function color$2(aValue1, aValue2) { - var a; - if (aValue1 & 4278190080) { - a = Math.round(255 * (aValue2 / colorModeA)); - a = a > 255 ? 255 : a; - a = a < 0 ? 0 : a; - return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) - } - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) - } - function color$1(aValue1) { - if (aValue1 <= colorModeX && aValue1 >= 0) { - if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); - if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) - } - if (aValue1) { - if (aValue1 > 2147483647) aValue1 -= 4294967296; - return aValue1 - } - } - p.color = function(aValue1, aValue2, aValue3, aValue4) { - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); - if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); - if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); - if (typeof aValue1 === "number") return color$1(aValue1); - return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) - }; - p.color.toString = function(colorInt) { - return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" - }; - p.color.toInt = function(r, g, b, a) { - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.color.toArray = function(colorInt) { - return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] - }; - p.color.toGLArray = function(colorInt) { - return [((colorInt >> 16) & 255) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt & 4278190080) >>> 24) / 255] - }; - p.color.toRGB = function(h, s, b) { - h = h > colorModeX ? colorModeX : h; - s = s > colorModeY ? colorModeY : s; - b = b > colorModeZ ? colorModeZ : b; - h = h / colorModeX * 360; - s = s / colorModeY * 100; - b = b / colorModeZ * 100; - var br = Math.round(b / 100 * 255); - if (s === 0) return [br, br, br]; - var hue = h % 360; - var f = hue % 60; - var p = Math.round(b * (100 - s) / 1E4 * 255); - var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); - var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255); - switch (Math.floor(hue / 60)) { - case 0: - return [br, t, p]; - case 1: - return [q, br, p]; - case 2: - return [p, br, t]; - case 3: - return [p, q, br]; - case 4: - return [t, p, br]; - case 5: - return [br, p, q] - } - }; - - function colorToHSB(colorInt) { - var red, green, blue; - red = ((colorInt >> 16) & 255) / 255; - green = ((colorInt >> 8) & 255) / 255; - blue = (colorInt & 255) / 255; - var max = p.max(p.max(red, green), blue), - min = p.min(p.min(red, green), blue), - hue, saturation; - if (min === max) return [0, 0, max * colorModeZ]; - saturation = (max - min) / max; - if (red === max) hue = (green - blue) / (max - min); - else if (green === max) hue = 2 + (blue - red) / (max - min); - else hue = 4 + (red - green) / (max - min); - hue /= 6; - if (hue < 0) hue += 1; - else if (hue > 1) hue -= 1; - return [hue * colorModeX, saturation * colorModeY, max * colorModeZ] - } - p.brightness = function(colInt) { - return colorToHSB(colInt)[2] - }; - p.saturation = function(colInt) { - return colorToHSB(colInt)[1] - }; - p.hue = function(colInt) { - return colorToHSB(colInt)[0] - }; - p.red = function(aColor) { - return ((aColor >> 16) & 255) / 255 * colorModeX - }; - p.green = function(aColor) { - return ((aColor >> 8) & 255) / 255 * colorModeY - }; - p.blue = function(aColor) { - return (aColor & 255) / 255 * colorModeZ - }; - p.alpha = function(aColor) { - return ((aColor >> 24) & 255) / 255 * colorModeA - }; - p.lerpColor = function(c1, c2, amt) { - var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; - var hsb1, hsb2, rgb, h, s; - var colorBits1 = p.color(c1); - var colorBits2 = p.color(c2); - if (curColorMode === 3) { - hsb1 = colorToHSB(colorBits1); - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - hsb2 = colorToHSB(colorBits2); - a2 = ((colorBits2 >> 24) & 255) / colorModeA; - h = p.lerp(hsb1[0], hsb2[0], amt); - s = p.lerp(hsb1[1], hsb2[1], amt); - b = p.lerp(hsb1[2], hsb2[2], amt); - rgb = p.color.toRGB(h, s, b); - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 - } - r1 = (colorBits1 >> 16) & 255; - g1 = (colorBits1 >> 8) & 255; - b1 = colorBits1 & 255; - a1 = ((colorBits1 >> 24) & 255) / colorModeA; - r2 = (colorBits2 >> 16) & 255; - g2 = (colorBits2 >> 8) & 255; - b2 = colorBits2 & 255; - a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; - r = p.lerp(r1, r2, amt) | 0; - g = p.lerp(g1, g2, amt) | 0; - b = p.lerp(b1, b2, amt) | 0; - a = p.lerp(a1, a2, amt) * colorModeA; - return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 - }; - p.colorMode = function() { - curColorMode = arguments[0]; - if (arguments.length > 1) { - colorModeX = arguments[1]; - colorModeY = arguments[2] || arguments[1]; - colorModeZ = arguments[3] || arguments[1]; - colorModeA = arguments[4] || arguments[1] - } - }; - p.blendColor = function(c1, c2, mode) { - if (mode === 0) return p.modes.replace(c1, c2); - else if (mode === 1) return p.modes.blend(c1, c2); - else if (mode === 2) return p.modes.add(c1, c2); - else if (mode === 4) return p.modes.subtract(c1, c2); - else if (mode === 8) return p.modes.lightest(c1, c2); - else if (mode === 16) return p.modes.darkest(c1, c2); - else if (mode === 32) return p.modes.difference(c1, c2); - else if (mode === 64) return p.modes.exclusion(c1, c2); - else if (mode === 128) return p.modes.multiply(c1, c2); - else if (mode === 256) return p.modes.screen(c1, c2); - else if (mode === 1024) return p.modes.hard_light(c1, c2); - else if (mode === 2048) return p.modes.soft_light(c1, c2); - else if (mode === 512) return p.modes.overlay(c1, c2); - else if (mode === 4096) return p.modes.dodge(c1, c2); - else if (mode === 8192) return p.modes.burn(c1, c2) - }; - - function saveContext() { - curContext.save() - } - function restoreContext() { - curContext.restore(); - isStrokeDirty = true; - isFillDirty = true - } - p.printMatrix = function() { - modelView.print() - }; - Drawing2D.prototype.translate = function(x, y) { - modelView.translate(x, y); - modelViewInv.invTranslate(x, y); - curContext.translate(x, y) - }; - Drawing3D.prototype.translate = function(x, y, z) { - modelView.translate(x, y, z); - modelViewInv.invTranslate(x, y, z) - }; - Drawing2D.prototype.scale = function(x, y) { - modelView.scale(x, y); - modelViewInv.invScale(x, y); - curContext.scale(x, y || x) - }; - Drawing3D.prototype.scale = function(x, y, z) { - modelView.scale(x, y, z); - modelViewInv.invScale(x, y, z) - }; - Drawing2D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv); - saveContext() - }; - Drawing3D.prototype.pushMatrix = function() { - userMatrixStack.load(modelView); - userReverseMatrixStack.load(modelViewInv) - }; - Drawing2D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()); - restoreContext() - }; - Drawing3D.prototype.popMatrix = function() { - modelView.set(userMatrixStack.pop()); - modelViewInv.set(userReverseMatrixStack.pop()) - }; - Drawing2D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset(); - curContext.setTransform(1, 0, 0, 1, 0, 0) - }; - Drawing3D.prototype.resetMatrix = function() { - modelView.reset(); - modelViewInv.reset() - }; - DrawingShared.prototype.applyMatrix = function() { - var a = arguments; - modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]) - }; - Drawing2D.prototype.applyMatrix = function() { - var a = arguments; - for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; - a[10] = a[15] = 1; - DrawingShared.prototype.applyMatrix.apply(this, a) - }; - p.rotateX = function(angleInRadians) { - modelView.rotateX(angleInRadians); - modelViewInv.invRotateX(angleInRadians) - }; - Drawing2D.prototype.rotateZ = function() { - throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; - }; - Drawing3D.prototype.rotateZ = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians) - }; - p.rotateY = function(angleInRadians) { - modelView.rotateY(angleInRadians); - modelViewInv.invRotateY(angleInRadians) - }; - Drawing2D.prototype.rotate = function(angleInRadians) { - modelView.rotateZ(angleInRadians); - modelViewInv.invRotateZ(angleInRadians); - curContext.rotate(angleInRadians) - }; - Drawing3D.prototype.rotate = function(angleInRadians) { - p.rotateZ(angleInRadians) - }; - p.pushStyle = function() { - saveContext(); - p.pushMatrix(); - var newState = { - "doFill": doFill, - "currentFillColor": currentFillColor, - "doStroke": doStroke, - "currentStrokeColor": currentStrokeColor, - "curTint": curTint, - "curRectMode": curRectMode, - "curColorMode": curColorMode, - "colorModeX": colorModeX, - "colorModeZ": colorModeZ, - "colorModeY": colorModeY, - "colorModeA": colorModeA, - "curTextFont": curTextFont, - "horizontalTextAlignment": horizontalTextAlignment, - "verticalTextAlignment": verticalTextAlignment, - "textMode": textMode, - "curFontName": curFontName, - "curTextSize": curTextSize, - "curTextAscent": curTextAscent, - "curTextDescent": curTextDescent, - "curTextLeading": curTextLeading - }; - styleArray.push(newState) - }; - p.popStyle = function() { - var oldState = styleArray.pop(); - if (oldState) { - restoreContext(); - p.popMatrix(); - doFill = oldState.doFill; - currentFillColor = oldState.currentFillColor; - doStroke = oldState.doStroke; - currentStrokeColor = oldState.currentStrokeColor; - curTint = oldState.curTint; - curRectMode = oldState.curRectmode; - curColorMode = oldState.curColorMode; - colorModeX = oldState.colorModeX; - colorModeZ = oldState.colorModeZ; - colorModeY = oldState.colorModeY; - colorModeA = oldState.colorModeA; - curTextFont = oldState.curTextFont; - curFontName = oldState.curFontName; - curTextSize = oldState.curTextSize; - horizontalTextAlignment = oldState.horizontalTextAlignment; - verticalTextAlignment = oldState.verticalTextAlignment; - textMode = oldState.textMode; - curTextAscent = oldState.curTextAscent; - curTextDescent = oldState.curTextDescent; - curTextLeading = oldState.curTextLeading - } else throw "Too many popStyle() without enough pushStyle()"; - }; - p.year = function() { - return (new Date).getFullYear() - }; - p.month = function() { - return (new Date).getMonth() + 1 - }; - p.day = function() { - return (new Date).getDate() - }; - p.hour = function() { - return (new Date).getHours() - }; - p.minute = function() { - return (new Date).getMinutes() - }; - p.second = function() { - return (new Date).getSeconds() - }; - p.millis = function() { - return Date.now() - start - }; - - function redrawHelper() { - var sec = (Date.now() - timeSinceLastFPS) / 1E3; - framesSinceLastFPS++; - var fps = framesSinceLastFPS / sec; - if (sec > 0.5) { - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - p.__frameRate = fps - } - p.frameCount++ - } - Drawing2D.prototype.redraw = function() { - redrawHelper(); - curContext.lineWidth = lineWidth; - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - saveContext(); - p.draw(); - restoreContext(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - Drawing3D.prototype.redraw = function() { - redrawHelper(); - var pmouseXLastEvent = p.pmouseX, - pmouseYLastEvent = p.pmouseY; - p.pmouseX = pmouseXLastFrame; - p.pmouseY = pmouseYLastFrame; - curContext.clear(curContext.DEPTH_BUFFER_BIT); - curContextCache = { - attributes: {}, - locations: {} - }; - p.noLights(); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - p.camera(); - p.draw(); - pmouseXLastFrame = p.mouseX; - pmouseYLastFrame = p.mouseY; - p.pmouseX = pmouseXLastEvent; - p.pmouseY = pmouseYLastEvent - }; - p.noLoop = function() { - doLoop = false; - loopStarted = false; - clearInterval(looping); - curSketch.onPause() - }; - p.loop = function() { - if (loopStarted) return; - timeSinceLastFPS = Date.now(); - framesSinceLastFPS = 0; - looping = window.setInterval(function() { - try { - curSketch.onFrameStart(); - p.redraw(); - curSketch.onFrameEnd() - } catch(e_loop) { - window.clearInterval(looping); - throw e_loop; - } - }, - curMsPerFrame); - doLoop = true; - loopStarted = true; - curSketch.onLoop() - }; - p.frameRate = function(aRate) { - curFrameRate = aRate; - curMsPerFrame = 1E3 / curFrameRate; - if (doLoop) { - p.noLoop(); - p.loop() - } - }; - var eventHandlers = []; - - function attachEventHandler(elem, type, fn) { - if (elem.addEventListener) elem.addEventListener(type, fn, false); - else elem.attachEvent("on" + type, fn); - eventHandlers.push({ - elem: elem, - type: type, - fn: fn - }) - } - function detachEventHandler(eventHandler) { - var elem = eventHandler.elem, - type = eventHandler.type, - fn = eventHandler.fn; - if (elem.removeEventListener) elem.removeEventListener(type, fn, false); - else if (elem.detachEvent) elem.detachEvent("on" + type, fn) - } - p.exit = function() { - window.clearInterval(looping); - removeInstance(p.externals.canvas.id); - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); - var i = eventHandlers.length; - while (i--) detachEventHandler(eventHandlers[i]); - curSketch.onExit() - }; - p.cursor = function() { - if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) { - var image = arguments[0], - x, y; - if (arguments.length >= 3) { - x = arguments[1]; - y = arguments[2]; - if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image"; - } else { - x = image.width >>> 1; - y = image.height >>> 1 - } - var imageDataURL = image.toDataURL(); - var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default"; - curCursor = curElement.style.cursor = style - } else if (arguments.length === 1) { - var mode = arguments[0]; - curCursor = curElement.style.cursor = mode - } else curCursor = curElement.style.cursor = oldCursor - }; - p.noCursor = function() { - curCursor = curElement.style.cursor = PConstants.NOCURSOR - }; - p.link = function(href, target) { - if (target !== undef) window.open(href, target); - else window.location = href - }; - p.beginDraw = nop; - p.endDraw = nop; - Drawing2D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - return curContext.getImageData(x, y, w, h) - }; - Drawing3D.prototype.toImageData = function(x, y, w, h) { - x = x !== undef ? x : 0; - y = y !== undef ? y : 0; - w = w !== undef ? w : p.width; - h = h !== undef ? h : p.height; - var c = document.createElement("canvas"), - ctx = c.getContext("2d"), - obj = ctx.createImageData(w, h), - uBuff = new Uint8Array(w * h * 4); - curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); - for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; - return obj - }; - p.status = function(text) { - window.status = text - }; - p.binary = function(num, numBits) { - var bit; - if (numBits > 0) bit = numBits; - else if (num instanceof Char) { - bit = 16; - num |= 0 - } else { - bit = 32; - while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- - } - var result = ""; - while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; - return result - }; - p.unbinary = function(binaryString) { - var i = binaryString.length - 1, - mask = 1, - result = 0; - while (i >= 0) { - var ch = binaryString[i--]; - if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; - if (ch === "1") result += mask; - mask <<= 1 - } - return result - }; - - function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) { - var sign = value < 0 ? minus : plus; - var autoDetectDecimals = rightDigits === 0; - var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits; - var absValue = Math.abs(value); - if (autoDetectDecimals) { - rightDigitsOfDefault = 1; - absValue *= 10; - while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) { - ++rightDigitsOfDefault; - absValue *= 10 - } - } else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault); - var number, doubled = absValue * 2; - if (Math.floor(absValue) === absValue) number = absValue; - else if (Math.floor(doubled) === doubled) { - var floored = Math.floor(absValue); - number = floored + floored % 2 - } else number = Math.round(absValue); - var buffer = ""; - var totalDigits = leftDigits + rightDigitsOfDefault; - while (totalDigits > 0 || number > 0) { - totalDigits--; - buffer = "" + number % 10 + buffer; - number = Math.floor(number / 10) - } - if (group !== undef) { - var i = buffer.length - 3 - rightDigitsOfDefault; - while (i > 0) { - buffer = buffer.substring(0, i) + group + buffer.substring(i); - i -= 3 - } - } - if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length); - return sign + buffer - } - function nfCore(value, plus, minus, leftDigits, rightDigits, group) { - if (value instanceof Array) { - var arr = []; - for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group)); - return arr - } - return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) - } - p.nf = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits) - }; - p.nfs = function(value, leftDigits, rightDigits) { - return nfCore(value, " ", "-", leftDigits, rightDigits) - }; - p.nfp = function(value, leftDigits, rightDigits) { - return nfCore(value, "+", "-", leftDigits, rightDigits) - }; - p.nfc = function(value, leftDigits, rightDigits) { - return nfCore(value, "", "-", leftDigits, rightDigits, ",") - }; - var decimalToHex = function(d, padding) { - padding = padding === undef || padding === null ? padding = 8 : padding; - if (d < 0) d = 4294967295 + d + 1; - var hex = Number(d).toString(16).toUpperCase(); - while (hex.length < padding) hex = "0" + hex; - if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length); - return hex - }; - p.hex = function(value, len) { - if (arguments.length === 1) if (value instanceof Char) len = 4; - else len = 8; - return decimalToHex(value, len) - }; - - function unhexScalar(hex) { - var value = parseInt("0x" + hex, 16); - if (value > 2147483647) value -= 4294967296; - return value - } - p.unhex = function(hex) { - if (hex instanceof Array) { - var arr = []; - for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i])); - return arr - } - return unhexScalar(hex) - }; - p.loadStrings = function(filename) { - if (localStorage[filename]) return localStorage[filename].split("\n"); - var filecontent = ajax(filename); - if (typeof filecontent !== "string" || filecontent === "") return []; - filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, ""); - return filecontent.split("\n") - }; - p.saveStrings = function(filename, strings) { - localStorage[filename] = strings.join("\n") - }; - p.loadBytes = function(url) { - var string = ajax(url); - var ret = []; - for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); - return ret - }; - - function removeFirstArgument(args) { - return Array.prototype.slice.call(args, 1) - } - p.matchAll = function(aString, aRegExp) { - var results = [], - latest; - var regexp = new RegExp(aRegExp, "g"); - while ((latest = regexp.exec(aString)) !== null) { - results.push(latest); - if (latest[0].length === 0)++regexp.lastIndex - } - return results.length > 0 ? results : null - }; - p.__contains = function(subject, subStr) { - if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); - return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 - }; - p.__replaceAll = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, "g"), replacement) - }; - p.__replaceFirst = function(subject, regex, replacement) { - if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); - return subject.replace(new RegExp(regex, ""), replacement) - }; - p.__replace = function(subject, what, replacement) { - if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); - if (what instanceof RegExp) return subject.replace(what, replacement); - if (typeof what !== "string") what = what.toString(); - if (what === "") return subject; - var i = subject.indexOf(what); - if (i < 0) return subject; - var j = 0, - result = ""; - do { - result += subject.substring(j, i) + replacement; - j = i + what.length - } while ((i = subject.indexOf(what, j)) >= 0); - return result + subject.substring(j) - }; - p.__equals = function(subject, other) { - if (subject.equals instanceof Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); - return subject.valueOf() === other.valueOf() - }; - p.__equalsIgnoreCase = function(subject, other) { - if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); - return subject.toLowerCase() === other.toLowerCase() - }; - p.__toCharArray = function(subject) { - if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); - var chars = []; - for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); - return chars - }; - p.__split = function(subject, regex, limit) { - if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); - var pattern = new RegExp(regex); - if (limit === undef || limit < 1) return subject.split(pattern); - var result = [], - currSubject = subject, - pos; - while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { - var match = pattern.exec(currSubject).toString(); - result.push(currSubject.substring(0, pos)); - currSubject = currSubject.substring(pos + match.length) - } - if (pos !== -1 || currSubject !== "") result.push(currSubject); - return result - }; - p.__codePointAt = function(subject, idx) { - var code = subject.charCodeAt(idx), - hi, low; - if (55296 <= code && code <= 56319) { - hi = code; - low = subject.charCodeAt(idx + 1); - return (hi - 55296) * 1024 + (low - 56320) + 65536 - } - return code - }; - p.match = function(str, regexp) { - return str.match(regexp) - }; - p.__startsWith = function(subject, prefix, toffset) { - if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); - toffset = toffset || 0; - if (toffset < 0 || toffset > subject.length) return false; - return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset - }; - p.__endsWith = function(subject, suffix) { - if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); - var suffixLen = suffix ? suffix.length : 0; - return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen - }; - p.__hashCode = function(subject) { - if (subject.hashCode instanceof Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); - return virtHashCode(subject) - }; - p.__printStackTrace = function(subject) { - p.println("Exception: " + subject.toString()) - }; - var logBuffer = []; - p.println = function(message) { - var bufferLen = logBuffer.length; - if (bufferLen) { - Processing.logger.log(logBuffer.join("")); - logBuffer.length = 0 - } - if (arguments.length === 0 && bufferLen === 0) Processing.logger.log(""); - else if (arguments.length !== 0) Processing.logger.log(message) - }; - p.print = function(message) { - logBuffer.push(message) - }; - p.str = function(val) { - if (val instanceof Array) { - var arr = []; - for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); - return arr - } - return val.toString() + "" - }; - p.trim = function(str) { - if (str instanceof Array) { - var arr = []; - for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")); - return arr - } - return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") - }; - - function booleanScalar(val) { - if (typeof val === "number") return val !== 0; - if (typeof val === "boolean") return val; - if (typeof val === "string") return val.toLowerCase() === "true"; - if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 - } - p.parseBoolean = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); - return ret - } - return booleanScalar(val) - }; - p.parseByte = function(what) { - if (what instanceof - Array) { - var bytes = []; - for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); - return bytes - } - return 0 - (what & 128) | what & 127 - }; - p.parseChar = function(key) { - if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); - if (key instanceof Array) { - var ret = []; - for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535))); - return ret - } - throw "char() may receive only one argument of type int, byte, int[], or byte[]."; - }; - - function floatScalar(val) { - if (typeof val === "number") return val; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") return parseFloat(val); - if (val instanceof Char) return val.code - } - p.parseFloat = function(val) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); - return ret - } - return floatScalar(val) - }; - - function intScalar(val, radix) { - if (typeof val === "number") return val & 4294967295; - if (typeof val === "boolean") return val ? 1 : 0; - if (typeof val === "string") { - var number = parseInt(val, radix || 10); - return number & 4294967295 - } - if (val instanceof - Char) return val.code - } - p.parseInt = function(val, radix) { - if (val instanceof Array) { - var ret = []; - for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0); - else ret.push(intScalar(val[i], radix)); - return ret - } - return intScalar(val, radix) - }; - p.__int_cast = function(val) { - return 0 | val - }; - p.__instanceof = function(obj, type) { - if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; - if (typeof obj === "string") return type === Object || type === String; - if (obj instanceof type) return true; - if (typeof obj !== "object" || obj === null) return false; - var objType = obj.constructor; - if (type.$isInterface) { - var interfaces = []; - while (objType) { - if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); - objType = objType.$base - } - while (interfaces.length > 0) { - var i = interfaces.shift(); - if (i === type) return true; - if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) - } - return false - } - while (objType.hasOwnProperty("$base")) { - objType = objType.$base; - if (objType === type) return true - } - return false - }; - p.abs = Math.abs; - p.ceil = Math.ceil; - p.constrain = function(aNumber, aMin, aMax) { - return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber - }; - p.dist = function() { - var dx, dy, dz; - if (arguments.length === 4) { - dx = arguments[0] - arguments[2]; - dy = arguments[1] - arguments[3]; - return Math.sqrt(dx * dx + dy * dy) - } - if (arguments.length === 6) { - dx = arguments[0] - arguments[3]; - dy = arguments[1] - arguments[4]; - dz = arguments[2] - arguments[5]; - return Math.sqrt(dx * dx + dy * dy + dz * dz) - } - }; - p.exp = Math.exp; - p.floor = Math.floor; - p.lerp = function(value1, value2, amt) { - return (value2 - value1) * amt + value1 - }; - p.log = Math.log; - p.mag = function(a, b, c) { - if (c) return Math.sqrt(a * a + b * b + c * c); - return Math.sqrt(a * a + b * b) - }; - p.map = function(value, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) - }; - p.max = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var max = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i]; - return max - }; - p.min = function() { - if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1]; - var numbers = arguments.length === 1 ? arguments[0] : arguments; - if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected"; - var min = numbers[0], - count = numbers.length; - for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i]; - return min - }; - p.norm = function(aNumber, low, high) { - return (aNumber - low) / (high - low) - }; - p.pow = Math.pow; - p.round = Math.round; - p.sq = function(aNumber) { - return aNumber * aNumber - }; - p.sqrt = Math.sqrt; - p.acos = Math.acos; - p.asin = Math.asin; - p.atan = Math.atan; - p.atan2 = Math.atan2; - p.cos = Math.cos; - p.degrees = function(aAngle) { - return aAngle * 180 / Math.PI - }; - p.radians = function(aAngle) { - return aAngle / 180 * Math.PI - }; - p.sin = Math.sin; - p.tan = Math.tan; - var currentRandom = Math.random; - p.random = function() { - if (arguments.length === 0) return currentRandom(); - if (arguments.length === 1) return currentRandom() * arguments[0]; - var aMin = arguments[0], - aMax = arguments[1]; - return currentRandom() * (aMax - aMin) + aMin - }; - - function Marsaglia(i1, i2) { - var z = i1 || 362436069, - w = i2 || 521288629; - var nextInt = function() { - z = 36969 * (z & 65535) + (z >>> 16) & 4294967295; - w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295; - return ((z & 65535) << 16 | w & 65535) & 4294967295 - }; - this.nextDouble = function() { - var i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i - }; - this.nextInt = nextInt - } - Marsaglia.createRandomized = function() { - var now = new Date; - return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295) - }; - p.randomSeed = function(seed) { - currentRandom = (new Marsaglia(seed)).nextDouble - }; - p.Random = function(seed) { - var haveNextNextGaussian = false, - nextNextGaussian, random; - this.nextGaussian = function() { - if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian - } - var v1, v2, s; - do { - v1 = 2 * random() - 1; - v2 = 2 * random() - 1; - s = v1 * v1 + v2 * v2 - } while (s >= 1 || s === 0); - var multiplier = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier - }; - random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble - }; - - function PerlinNoise(seed) { - var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized(); - var i, j; - var perm = new Uint8Array(512); - for (i = 0; i < 256; ++i) perm[i] = i; - for (i = 0; i < 256; ++i) { - var t = perm[j = rnd.nextInt() & 255]; - perm[j] = perm[i]; - perm[i] = t - } - for (i = 0; i < 256; ++i) perm[i + 256] = perm[i]; - - function grad3d(i, x, y, z) { - var h = i & 15; - var u = h < 8 ? x : y, - v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v) - } - function grad2d(i, x, y) { - var v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v - } - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x - } - function lerp(t, a, b) { - return a + t * (b - a) - } - this.noise3d = function(x, y, z) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255, - Z = Math.floor(z) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - z -= Math.floor(z); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y, - fz = (3 - 2 * z) * z * z; - var p0 = perm[X] + Y, - p00 = perm[p0] + Z, - p01 = perm[p0 + 1] + Z, - p1 = perm[X + 1] + Y, - p10 = perm[p1] + Z, - p11 = perm[p1 + 1] + Z; - return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1)))) - }; - this.noise2d = function(x, y) { - var X = Math.floor(x) & 255, - Y = Math.floor(y) & 255; - x -= Math.floor(x); - y -= Math.floor(y); - var fx = (3 - 2 * x) * x * x, - fy = (3 - 2 * y) * y * y; - var p0 = perm[X] + Y, - p1 = perm[X + 1] + Y; - return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1))) - }; - this.noise1d = function(x) { - var X = Math.floor(x) & 255; - x -= Math.floor(x); - var fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1)) - } - } - var noiseProfile = { - generator: undef, - octaves: 4, - fallout: 0.5, - seed: undef - }; - p.noise = function(x, y, z) { - if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - var generator = noiseProfile.generator; - var effect = 1, - k = 1, - sum = 0; - for (var i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; - break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; - break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; - break - } - k *= 2 - } - return sum - }; - p.noiseDetail = function(octaves, fallout) { - noiseProfile.octaves = octaves; - if (fallout !== undef) noiseProfile.fallout = fallout - }; - p.noiseSeed = function(seed) { - noiseProfile.seed = seed; - noiseProfile.generator = undef - }; - DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { - if (doStroke) p.stroke(0); - if (doFill) p.fill(255); - var savedProperties = { - fillStyle: curContext.fillStyle, - strokeStyle: curContext.strokeStyle, - lineCap: curContext.lineCap, - lineJoin: curContext.lineJoin - }; - if (curElement.style.length > 0) { - curElement.style.removeProperty("width"); - curElement.style.removeProperty("height") - } - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; - p.textFont(curTextFont); - p.background(); - maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); - p.externals.context = curContext; - for (var i = 0; i < 720; i++) { - sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); - cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) - } - }; - Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { - if (curContext === undef) { - curContext = curElement.getContext("2d"); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - modelView = new PMatrix2D; - modelViewInv = new PMatrix2D - } - DrawingShared.prototype.size.apply(this, arguments) - }; - Drawing3D.prototype.size = function() { - var size3DCalled = false; - return function size(aWidth, aHeight, aMode) { - if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; - size3DCalled = true; - - function getGLContext(canvas) { - var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], - gl; - for (var i = 0, l = ctxNames.length; i < l; i++) { - gl = canvas.getContext(ctxNames[i], { - antialias: false - }); - if (gl) break - } - return gl - } - try { - curElement.width = p.width = aWidth || 100; - curElement.height = p.height = aHeight || 100; - curContext = getGLContext(curElement); - canTex = curContext.createTexture(); - textTex = curContext.createTexture() - } catch(e_size) { - Processing.debug(e_size) - } - if (!curContext) throw "WebGL context is not supported on this browser."; - curContext.viewport(0, 0, curElement.width, curElement.height); - curContext.enable(curContext.DEPTH_TEST); - curContext.enable(curContext.BLEND); - curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA); - programObject2D = createProgramObject(curContext, vertexShaderSource2D, fragmentShaderSource2D); - programObjectUnlitShape = createProgramObject(curContext, vShaderSrcUnlitShape, fShaderSrcUnlitShape); - p.strokeWeight(1); - programObject3D = createProgramObject(curContext, vertexShaderSource3D, fragmentShaderSource3D); - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - p.lightFalloff(1, 0, 0); - p.shininess(1); - p.ambient(255, 255, 255); - p.specular(0, 0, 0); - p.emissive(0, 0, 0); - boxBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW); - boxNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW); - boxOutlineBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW); - rectBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW); - rectNormBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW); - sphereBuffer = curContext.createBuffer(); - lineBuffer = curContext.createBuffer(); - fillBuffer = curContext.createBuffer(); - fillColorBuffer = curContext.createBuffer(); - strokeColorBuffer = curContext.createBuffer(); - shapeTexVBO = curContext.createBuffer(); - pointBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW); - textBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW); - textureBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW); - indexBuffer = curContext.createBuffer(); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, - 1, 2, 2, 3, 0]), curContext.STATIC_DRAW); - cam = new PMatrix3D; - cameraInv = new PMatrix3D; - modelView = new PMatrix3D; - modelViewInv = new PMatrix3D; - projection = new PMatrix3D; - p.camera(); - p.perspective(); - userMatrixStack = new PMatrixStack; - userReverseMatrixStack = new PMatrixStack; - curveBasisMatrix = new PMatrix3D; - curveToBezierMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - bezierDrawMatrix = new PMatrix3D; - bezierBasisInverse = new PMatrix3D; - bezierBasisMatrix = new PMatrix3D; - bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0); - DrawingShared.prototype.size.apply(this, arguments) - } - }(); - Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col & 65280) >>> 8) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 0); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", dir); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 1); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { - curContext.useProgram(programObject3D); - uniformf("falloff3d", programObject3D, "falloff", [constant, linear, quadratic]) - }; - Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.lightSpecular = function(r, g, b) { - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("specular3d", programObject3D, "specular", normalizedCol) - }; - p.lights = function() { - p.ambientLight(128, 128, 128); - p.directionalLight(128, 128, 128, 0, 0, -1); - p.lightFalloff(1, 0, 0); - p.lightSpecular(0, 0, 0) - }; - Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - var pos = new PVector(x, y, z); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.mult(pos, pos); - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - curContext.useProgram(programObject3D); - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 2); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.noLights = function() { - lightCount = 0; - curContext.useProgram(programObject3D); - uniformi("lightCount3d", programObject3D, "lightCount", lightCount) - }; - Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { - if (lightCount === 8) throw "can only create " + 8 + " lights"; - curContext.useProgram(programObject3D); - var pos = new PVector(x, y, z); - var mvm = new PMatrix3D; - mvm.scale(1, -1, 1); - mvm.apply(modelView.array()); - mvm.mult(pos, pos); - mvm = mvm.array(); - var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; - var col = color$4(r, g, b, 0); - var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; - uniformf("lights.color.3d." + lightCount, programObject3D, "lights" + lightCount + ".color", normalizedCol); - uniformf("lights.position.3d." + lightCount, programObject3D, "lights" + lightCount + ".position", pos.array()); - uniformf("lights.direction.3d." + lightCount, programObject3D, "lights" + lightCount + ".direction", dir); - uniformf("lights.concentration.3d." + lightCount, programObject3D, "lights" + lightCount + ".concentration", concentration); - uniformf("lights.angle.3d." + lightCount, programObject3D, "lights" + lightCount + ".angle", angle); - uniformi("lights.type.3d." + lightCount, programObject3D, "lights" + lightCount + ".type", 3); - uniformi("lightCount3d", programObject3D, "lightCount", ++lightCount) - }; - Drawing2D.prototype.beginCamera = function() { - throw "beginCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.beginCamera = function() { - if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; - manipulatingCamera = true; - modelView = cameraInv; - modelViewInv = cam - }; - Drawing2D.prototype.endCamera = function() { - throw "endCamera() is not available in 2D mode"; - }; - Drawing3D.prototype.endCamera = function() { - if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; - modelView.set(cam); - modelViewInv.set(cameraInv); - manipulatingCamera = false - }; - p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { - if (eyeX === undef) { - cameraX = p.width / 2; - cameraY = p.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - eyeX = cameraX; - eyeY = cameraY; - eyeZ = cameraZ; - centerX = cameraX; - centerY = cameraY; - centerZ = 0; - upX = 0; - upY = 1; - upZ = 0 - } - var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ); - var y = new PVector(upX, upY, upZ); - z.normalize(); - var x = PVector.cross(y, z); - y = PVector.cross(z, x); - x.normalize(); - y.normalize(); - var xX = x.x, - xY = x.y, - xZ = x.z; - var yX = y.x, - yY = y.y, - yZ = y.z; - var zX = z.x, - zY = z.y, - zZ = z.z; - cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cam.translate(-eyeX, -eyeY, -eyeZ); - cameraInv.reset(); - cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); - cameraInv.translate(eyeX, eyeY, eyeZ); - modelView.set(cam); - modelViewInv.set(cameraInv) - }; - p.perspective = function(fov, aspect, near, far) { - if (arguments.length === 0) { - cameraY = curElement.height / 2; - cameraZ = cameraY / Math.tan(cameraFOV / 2); - cameraNear = cameraZ / 10; - cameraFar = cameraZ * 10; - cameraAspect = p.width / p.height; - fov = cameraFOV; - aspect = cameraAspect; - near = cameraNear; - far = cameraFar - } - var yMax, yMin, xMax, xMin; - yMax = near * Math.tan(fov / 2); - yMin = -yMax; - xMax = yMax * aspect; - xMin = yMin * aspect; - p.frustum(xMin, xMax, yMin, yMax, near, far) - }; - Drawing2D.prototype.frustum = function() { - throw "Processing.js: frustum() is not supported in 2D mode"; - }; - Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) { - frustumMode = true; - projection = new PMatrix3D; - projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) - }; - p.ortho = function(left, right, bottom, top, near, far) { - if (arguments.length === 0) { - left = 0; - right = p.width; - bottom = 0; - top = p.height; - near = -10; - far = 10 - } - var x = 2 / (right - left); - var y = 2 / (top - bottom); - var z = -2 / (far - near); - var tx = -(right + left) / (right - left); - var ty = -(top + bottom) / (top - bottom); - var tz = -(far + near) / (far - near); - projection = new PMatrix3D; - projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - var proj = new PMatrix3D; - proj.set(projection); - proj.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("projection2d", programObject2D, "projection", false, proj.array()); - curContext.useProgram(programObject3D); - uniformMatrix("projection3d", programObject3D, "projection", false, proj.array()); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); - frustumMode = false - }; - p.printProjection = function() { - projection.print() - }; - p.printCamera = function() { - cam.print() - }; - Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.box = function(w, h, d) { - if (!h || !d) h = d = w; - var model = new PMatrix3D; - model.scale(w, h, d); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, boxNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, boxBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, boxOutlineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3) - } - }; - var initSphere = function() { - var i; - sphereVerts = []; - for (i = 0; i < sphereDetailU; i++) { - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[i]); - sphereVerts.push(sphereY[i]); - sphereVerts.push(sphereZ[i]) - } - sphereVerts.push(0); - sphereVerts.push(-1); - sphereVerts.push(0); - sphereVerts.push(sphereX[0]); - sphereVerts.push(sphereY[0]); - sphereVerts.push(sphereZ[0]); - var v1, v11, v2; - var voff = 0; - for (i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - for (var j = 0; j < sphereDetailU; j++) { - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1++]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2++]) - } - v1 = v11; - v2 = voff; - sphereVerts.push(sphereX[v1]); - sphereVerts.push(sphereY[v1]); - sphereVerts.push(sphereZ[v1]); - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]) - } - for (i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - sphereVerts.push(sphereX[v2]); - sphereVerts.push(sphereY[v2]); - sphereVerts.push(sphereZ[v2]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0) - } - sphereVerts.push(sphereX[voff]); - sphereVerts.push(sphereY[voff]); - sphereVerts.push(sphereZ[voff]); - sphereVerts.push(0); - sphereVerts.push(1); - sphereVerts.push(0); - curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW) - }; - p.sphereDetail = function(ures, vres) { - var i; - if (arguments.length === 1) ures = vres = arguments[0]; - if (ures < 3) ures = 3; - if (vres < 2) vres = 2; - if (ures === sphereDetailU && vres === sphereDetailV) return; - var delta = 720 / ures; - var cx = new Float32Array(ures); - var cz = new Float32Array(ures); - for (i = 0; i < ures; i++) { - cx[i] = cosLUT[i * delta % 720 | 0]; - cz[i] = sinLUT[i * delta % 720 | 0] - } - var vertCount = ures * (vres - 1) + 2; - var currVert = 0; - sphereX = new Float32Array(vertCount); - sphereY = new Float32Array(vertCount); - sphereZ = new Float32Array(vertCount); - var angle_step = 720 * 0.5 / vres; - var angle = angle_step; - for (i = 1; i < vres; i++) { - var curradius = sinLUT[angle % 720 | 0]; - var currY = -cosLUT[angle % 720 | 0]; - for (var j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius - } - angle += angle_step - } - sphereDetailU = ures; - sphereDetailV = vres; - initSphere() - }; - Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.sphere = function() { - var sRad = arguments[0]; - if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30); - var model = new PMatrix3D; - model.scale(sRad, sRad, sRad); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (doFill) { - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, sphereBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - curContext.useProgram(programObject3D); - disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, sphereBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) - } - }; - p.modelX = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? ox / ow : ox - }; - p.modelY = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oy / ow : oy - }; - p.modelZ = function(x, y, z) { - var mv = modelView.array(); - var ci = cameraInv.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw; - var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw; - return ow !== 0 ? oz / ow : oz - }; - Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.ambient = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_ambient3d", programObject3D, "mat_ambient", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.emissive = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_emissive3d", programObject3D, "mat_emissive", p.color.toGLArray(col).slice(0, 3)) - }; - Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.shininess = function(shine) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - uniformf("shininess3d", programObject3D, "shininess", shine) - }; - Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; - Drawing3D.prototype.specular = function(v1, v2, v3) { - curContext.useProgram(programObject3D); - uniformi("usingMat3d", programObject3D, "usingMat", true); - var col = p.color(v1, v2, v3); - uniformf("mat_specular3d", programObject3D, "mat_specular", p.color.toGLArray(col).slice(0, 3)) - }; - p.screenX = function(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) ox /= ow; - return p.width * (1 + ox) / 2 - } - return modelView.multX(x, y) - }; - p.screenY = function screenY(x, y, z) { - var mv = modelView.array(); - if (mv.length === 16) { - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var pj = projection.array(); - var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oy /= ow; - return p.height * (1 + oy) / 2 - } - return modelView.multY(x, y) - }; - p.screenZ = function screenZ(x, y, z) { - var mv = modelView.array(); - if (mv.length !== 16) return 0; - var pj = projection.array(); - var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3]; - var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7]; - var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11]; - var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15]; - var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw; - var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw; - if (ow !== 0) oz /= ow; - return (oz + 1) / 2 - }; - DrawingShared.prototype.fill = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentFillColor && doFill) return; - doFill = true; - currentFillColor = color - }; - Drawing2D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - isFillDirty = true - }; - Drawing3D.prototype.fill = function() { - DrawingShared.prototype.fill.apply(this, arguments); - fillStyle = p.color.toGLArray(currentFillColor) - }; - - function executeContextFill() { - if (doFill) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - curContext.fill() - } - } - p.noFill = function() { - doFill = false - }; - DrawingShared.prototype.stroke = function() { - var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); - if (color === currentStrokeColor && doStroke) return; - doStroke = true; - currentStrokeColor = color - }; - Drawing2D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - isStrokeDirty = true - }; - Drawing3D.prototype.stroke = function() { - DrawingShared.prototype.stroke.apply(this, arguments); - strokeStyle = p.color.toGLArray(currentStrokeColor) - }; - - function executeContextStroke() { - if (doStroke) { - if (isStrokeDirty) { - curContext.strokeStyle = p.color.toString(currentStrokeColor); - isStrokeDirty = false - } - curContext.stroke() - } - } - p.noStroke = function() { - doStroke = false - }; - DrawingShared.prototype.strokeWeight = function(w) { - lineWidth = w - }; - Drawing2D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.lineWidth = w - }; - Drawing3D.prototype.strokeWeight = function(w) { - DrawingShared.prototype.strokeWeight.apply(this, arguments); - curContext.useProgram(programObject2D); - uniformf("pointSize2d", programObject2D, "pointSize", w); - curContext.useProgram(programObjectUnlitShape); - uniformf("pointSizeUnlitShape", programObjectUnlitShape, "pointSize", w); - curContext.lineWidth(w) - }; - p.strokeCap = function(value) { - drawing.$ensureContext().lineCap = value - }; - p.strokeJoin = function(value) { - drawing.$ensureContext().lineJoin = value - }; - Drawing2D.prototype.smooth = function() { - renderSmooth = true; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeQuality", "important"); - style.setProperty("-ms-interpolation-mode", "bicubic", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true - }; - Drawing3D.prototype.smooth = nop; - Drawing2D.prototype.noSmooth = function() { - renderSmooth = false; - var style = curElement.style; - style.setProperty("image-rendering", "optimizeSpeed", "important"); - style.setProperty("image-rendering", "-moz-crisp-edges", "important"); - style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); - style.setProperty("image-rendering", "optimize-contrast", "important"); - style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); - if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false - }; - Drawing3D.prototype.noSmooth = nop; - Drawing2D.prototype.point = function(x, y) { - if (!doStroke) return; - x = Math.round(x); - y = Math.round(y); - curContext.fillStyle = p.color.toString(currentStrokeColor); - isFillDirty = true; - if (lineWidth > 1) { - curContext.beginPath(); - curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); - curContext.fill() - } else curContext.fillRect(x, y, 1, 1) - }; - Drawing3D.prototype.point = function(x, y, z) { - var model = new PMatrix3D; - model.translate(x, y, z || 0); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - if (lineWidth > 0 && doStroke) { - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, pointBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.POINTS, 0, 1) - } - }; - p.beginShape = function(type) { - curShape = type; - curvePoints = []; - vertArray = [] - }; - Drawing2D.prototype.vertex = function(x, y, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - vert[0] = x; - vert[1] = y; - vert[2] = 0; - vert[3] = u; - vert[4] = v; - vert[5] = currentFillColor; - vert[6] = currentStrokeColor; - vertArray.push(vert) - }; - Drawing3D.prototype.vertex = function(x, y, z, u, v) { - var vert = []; - if (firstVert) firstVert = false; - vert["isVert"] = true; - if (v === undef && usingTexture) { - v = u; - u = z; - z = 0 - } - if (u !== undef && v !== undef) { - if (curTextureMode === 2) { - u /= curTexture.width; - v /= curTexture.height - } - u = u > 1 ? 1 : u; - u = u < 0 ? 0 : u; - v = v > 1 ? 1 : v; - v = v < 0 ? 0 : v - } - vert[0] = x; - vert[1] = y; - vert[2] = z || 0; - vert[3] = u || 0; - vert[4] = v || 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.push(vert) - }; - var point3D = function(vArray, cArray) { - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3) - }; - var line3D = function(vArray, mode, cArray) { - var ctxMode; - if (mode === "LINES") ctxMode = curContext.LINES; - else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP; - else ctxMode = curContext.LINE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObjectUnlitShape); - uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); - vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - curContext.drawArrays(ctxMode, 0, vArray.length / 3) - }; - var fill3D = function(vArray, mode, cArray, tArray) { - var ctxMode; - if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES; - else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN; - else ctxMode = curContext.TRIANGLE_STRIP; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", [-1, 0, 0, 0]); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, fillBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); - if (usingTexture && curTint !== null) curTint3d(cArray); - vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); - disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - if (usingTexture) { - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture); - vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW) - } - curContext.drawArrays(ctxMode, 0, vArray.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - }; - - function fillStrokeClose() { - executeContextFill(); - executeContextStroke(); - curContext.closePath() - } - Drawing2D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - if (closeShape) vertArray.push(vertArray[0]); - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - if (vertArrayLength > 3) { - var b = [], - s = 1 - curTightness; - curContext.beginPath(); - curContext.moveTo(vertArray[1][0], vertArray[1][1]); - for (i = 1; i + 2 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - b[0] = [cachedVertArray[0], cachedVertArray[1]]; - b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + - (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6]; - b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6]; - b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]]; - curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]) - } - fillStrokeClose() - } - } else if (isBezier && (curShape === 20 || curShape === undef)) { - curContext.beginPath(); - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) - } - fillStrokeClose() - } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(cachedVertArray[6]); - p.point(cachedVertArray[0], cachedVertArray[1]) - } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - if (doStroke) p.stroke(vertArray[i + 1][6]); - p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) - } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 2][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doStroke) p.stroke(vertArray[i + 1][6]); - if (doFill) p.fill(vertArray[i + 1][5]); - if (i + 2 < vertArrayLength) { - curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); - if (doStroke) p.stroke(vertArray[i + 2][6]); - if (doFill) p.fill(vertArray[i + 2][5]) - } - fillStrokeClose() - } else if (curShape === 11) { - if (vertArrayLength > 2) { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[1][0], vertArray[1][1]); - curContext.lineTo(vertArray[2][0], vertArray[2][1]); - if (doFill) { - p.fill(vertArray[2][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[2][6]); - executeContextStroke() - } - curContext.closePath(); - for (i = 3; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(cachedVertArray[5]); - executeContextFill() - } - if (doStroke) { - p.stroke(cachedVertArray[6]); - executeContextStroke() - } - curContext.closePath() - } - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - if (doFill) { - p.fill(vertArray[i + 3][5]); - executeContextFill() - } - if (doStroke) { - p.stroke(vertArray[i + 3][6]); - executeContextStroke() - } - curContext.closePath() - } else if (curShape === 17) { - if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { - cachedVertArray = vertArray[i]; - curContext.beginPath(); - if (i + 3 < vertArrayLength) { - curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); - curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); - curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]); - if (doFill) p.fill(vertArray[i + 3][5]); - if (doStroke) p.stroke(vertArray[i + 3][6]) - } else { - curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) - } - fillStrokeClose() - } - } else { - curContext.beginPath(); - curContext.moveTo(vertArray[0][0], vertArray[0][1]); - for (i = 1; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); - else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) - } - fillStrokeClose() - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0; - if (closeShape) vertArray.pop() - }; - Drawing3D.prototype.endShape = function(mode) { - if (vertArray.length === 0) return; - var closeShape = mode === 2; - var lineVertArray = []; - var fillVertArray = []; - var colorVertArray = []; - var strokeVertArray = []; - var texVertArray = []; - var cachedVertArray; - firstVert = true; - var i, j, k; - var vertArrayLength = vertArray.length; - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - texVertArray.push(cachedVertArray[3]); - texVertArray.push(cachedVertArray[4]) - } - if (closeShape) { - fillVertArray.push(vertArray[0][0]); - fillVertArray.push(vertArray[0][1]); - fillVertArray.push(vertArray[0][2]); - for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]); - for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]); - texVertArray.push(vertArray[0][3]); - texVertArray.push(vertArray[0][4]) - } - if (isCurve && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, null, colorVertArray) - } else if (isBezier && (curShape === 20 || curShape === undef)) { - lineVertArray = fillVertArray; - lineVertArray.splice(lineVertArray.length - 3); - strokeVertArray.splice(strokeVertArray.length - 4); - if (doStroke) line3D(lineVertArray, null, strokeVertArray); - if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray) - } else { - if (curShape === 2) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - point3D(lineVertArray, strokeVertArray) - } else if (curShape === 4) { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINES", strokeVertArray) - } else if (curShape === 9) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) { - fillVertArray = []; - texVertArray = []; - lineVertArray = []; - colorVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - colorVertArray.push(vertArray[i + j][k]); - strokeVertArray.push(vertArray[i + j][k + 4]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray) - } - } else if (curShape === 10) { - if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) { - lineVertArray = []; - fillVertArray = []; - strokeVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) { - lineVertArray.push(vertArray[i + j][k]); - fillVertArray.push(vertArray[i + j][k]) - } - for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) { - strokeVertArray.push(vertArray[i + j][k + 4]); - colorVertArray.push(vertArray[i + j][k]) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray); - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray) - } - } else if (curShape === 11) { - if (vertArrayLength > 2) { - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 3; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - for (i = 2; i + 1 < vertArrayLength; i++) { - lineVertArray = []; - strokeVertArray = []; - lineVertArray.push(vertArray[0][0]); - lineVertArray.push(vertArray[0][1]); - lineVertArray.push(vertArray[0][2]); - strokeVertArray.push(vertArray[0][9]); - strokeVertArray.push(vertArray[0][10]); - strokeVertArray.push(vertArray[0][11]); - strokeVertArray.push(vertArray[0][12]); - for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]); - for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { - lineVertArray = []; - for (j = 0; j < 4; j++) { - cachedVertArray = vertArray[i + j]; - for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k]) - } - if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - if (doFill) { - fillVertArray = []; - colorVertArray = []; - texVertArray = []; - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]); - if (usingTexture) { - texVertArray.push(vertArray[i + 0][3]); - texVertArray.push(vertArray[i + 0][4]); - texVertArray.push(vertArray[i + 1][3]); - texVertArray.push(vertArray[i + 1][4]); - texVertArray.push(vertArray[i + 3][3]); - texVertArray.push(vertArray[i + 3][4]); - texVertArray.push(vertArray[i + 2][3]); - texVertArray.push(vertArray[i + 2][4]) - } - fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray) - } - } else if (curShape === 17) { - var tempArray = []; - if (vertArrayLength > 3) { - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) - } - for (i = 0; i < 2; i++) { - cachedVertArray = vertArray[i]; - for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) - } - line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { - tempArray = fillVertArray.splice(fillVertArray.length - 3); - vertArray.pop() - } - for (i = 0; i + 3 < vertArrayLength; i += 2) { - lineVertArray = []; - strokeVertArray = []; - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]); - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]); - if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray) - } - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray) - } - } else if (vertArrayLength === 1) { - for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]); - for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]); - point3D(lineVertArray, strokeVertArray) - } else { - for (i = 0; i < vertArrayLength; i++) { - cachedVertArray = vertArray[i]; - for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); - for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) - } - if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); - else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); - if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) - } - usingTexture = false; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - } - isCurve = false; - isBezier = false; - curveVertArray = []; - curveVertCount = 0 - }; - var splineForward = function(segments, matrix) { - var f = 1 / segments; - var ff = f * f; - var fff = ff * f; - matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0) - }; - var curveInit = function() { - if (!curveDrawMatrix) { - curveBasisMatrix = new PMatrix3D; - curveDrawMatrix = new PMatrix3D; - curveInited = true - } - var s = curTightness; - curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0); - splineForward(curveDet, curveDrawMatrix); - if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D; - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - curveDrawMatrix.apply(curveBasisMatrix) - }; - Drawing2D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; - vertArray.push(vert); - vertArray[vertArray.length - 1]["isVert"] = false - }; - Drawing3D.prototype.bezierVertex = function() { - isBezier = true; - var vert = []; - if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; - if (arguments.length === 9) { - if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D; - var lastPoint = vertArray.length - 1; - splineForward(bezDetail, bezierDrawMatrix); - bezierDrawMatrix.apply(bezierBasisMatrix); - var draw = bezierDrawMatrix.array(); - var x1 = vertArray[lastPoint][0], - y1 = vertArray[lastPoint][1], - z1 = vertArray[lastPoint][2]; - var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6]; - var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6]; - var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6]; - var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7]; - var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7]; - var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7]; - var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8]; - var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8]; - var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8]; - for (var j = 0; j < bezDetail; j++) { - x1 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y1 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z1 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x1, y1, z1) - } - p.vertex(arguments[6], arguments[7], arguments[8]) - } - }; - p.texture = function(pimage) { - var curContext = drawing.$ensureContext(); - if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); - else if (pimage.localName === "canvas") { - curContext.bindTexture(curContext.TEXTURE_2D, canTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.generateMipmap(curContext.TEXTURE_2D); - curTexture.width = pimage.width; - curTexture.height = pimage.height - } else { - var texture = curContext.createTexture(), - cvs = document.createElement("canvas"), - cvsTextureCtx = cvs.getContext("2d"), - pot; - if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width; - else { - pot = 1; - while (pot < pimage.width) pot *= 2; - cvs.width = pot - } - if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height; - else { - pot = 1; - while (pot < pimage.height) pot *= 2; - cvs.height = pot - } - cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); - curContext.bindTexture(curContext.TEXTURE_2D, texture); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); - curContext.generateMipmap(curContext.TEXTURE_2D); - pimage.__texture = texture; - curTexture.width = pimage.width; - curTexture.height = pimage.height - } - usingTexture = true; - curContext.useProgram(programObject3D); - uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture) - }; - p.textureMode = function(mode) { - curTextureMode = mode - }; - var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { - var x0 = x2; - var y0 = y2; - var z0 = z2; - var draw = curveDrawMatrix.array(); - var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4; - var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4; - var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4; - var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4; - var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4; - var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4; - var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4; - var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4; - var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4; - p.vertex(x0, y0, z0); - for (var j = 0; j < curveDet; j++) { - x0 += xplot1; - xplot1 += xplot2; - xplot2 += xplot3; - y0 += yplot1; - yplot1 += yplot2; - yplot2 += yplot3; - z0 += zplot1; - zplot1 += zplot2; - zplot2 += zplot3; - p.vertex(x0, y0, z0) - } - }; - Drawing2D.prototype.curveVertex = function(x, y) { - isCurve = true; - p.vertex(x, y) - }; - Drawing3D.prototype.curveVertex = function(x, y, z) { - isCurve = true; - if (!curveInited) curveInit(); - var vert = []; - vert[0] = x; - vert[1] = y; - vert[2] = z; - curveVertArray.push(vert); - curveVertCount++; - if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2]) - }; - Drawing2D.prototype.curve = function() { - if (arguments.length === 8) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1]); - p.curveVertex(arguments[2], arguments[3]); - p.curveVertex(arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7]); - p.endShape() - } - }; - Drawing3D.prototype.curve = function() { - if (arguments.length === 12) { - p.beginShape(); - p.curveVertex(arguments[0], arguments[1], arguments[2]); - p.curveVertex(arguments[3], arguments[4], arguments[5]); - p.curveVertex(arguments[6], arguments[7], arguments[8]); - p.curveVertex(arguments[9], arguments[10], arguments[11]); - p.endShape() - } - }; - p.curveTightness = function(tightness) { - curTightness = tightness - }; - p.curveDetail = function(detail) { - curveDet = detail; - curveInit() - }; - p.rectMode = function(aRectMode) { - curRectMode = aRectMode - }; - p.imageMode = function(mode) { - switch (mode) { - case 0: - imageModeConvert = imageModeCorner; - break; - case 1: - imageModeConvert = imageModeCorners; - break; - case 3: - imageModeConvert = imageModeCenter; - break; - default: - throw "Invalid imageMode"; - } - }; - p.ellipseMode = function(aEllipseMode) { - curEllipseMode = aEllipseMode - }; - p.arc = function(x, y, width, height, start, stop) { - if (width <= 0 || stop < start) return; - if (curEllipseMode === 1) { - width = width - x; - height = height - y - } else if (curEllipseMode === 2) { - x = x - width; - y = y - height; - width = width * 2; - height = height * 2 - } else if (curEllipseMode === 3) { - x = x - width / 2; - y = y - height / 2 - } - while (start < 0) { - start += 6.283185307179586; - stop += 6.283185307179586 - } - if (stop - start > 6.283185307179586) { - start = 0; - stop = 6.283185307179586 - } - var hr = width / 2; - var vr = height / 2; - var centerX = x + hr; - var centerY = y + vr; - var startLUT = 0 | -0.5 + start * p.RAD_TO_DEG * 2; - var stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2; - var i, j; - if (doFill) { - var savedStroke = doStroke; - doStroke = false; - p.beginShape(); - p.vertex(centerX, centerY); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(2); - doStroke = savedStroke - } - if (doStroke) { - var savedFill = doFill; - doFill = false; - p.beginShape(); - for (i = startLUT; i <= stopLUT; i++) { - j = i % 720; - p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) - } - p.endShape(); - doFill = savedFill - } - }; - Drawing2D.prototype.line = function(x1, y1, x2, y2) { - if (!doStroke) return; - x1 = Math.round(x1); - x2 = Math.round(x2); - y1 = Math.round(y1); - y2 = Math.round(y2); - if (x1 === x2 && y1 === y2) { - p.point(x1, y1); - return - } - var swap = undef, - lineCap = undef, - drawCrisp = true, - currentModelView = modelView.array(), - identityMatrix = [1, 0, 0, 0, 1, 0]; - for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; - if (drawCrisp) { - if (x1 === x2) { - if (y1 > y2) { - swap = y1; - y1 = y2; - y2 = swap - } - y2++; - if (lineWidth % 2 === 1) curContext.translate(0.5, 0) - } else if (y1 === y2) { - if (x1 > x2) { - swap = x1; - x1 = x2; - x2 = swap - } - x2++; - if (lineWidth % 2 === 1) curContext.translate(0, 0.5) - } - if (lineWidth === 1) { - lineCap = curContext.lineCap; - curContext.lineCap = "butt" - } - } - curContext.beginPath(); - curContext.moveTo(x1 || 0, y1 || 0); - curContext.lineTo(x2 || 0, y2 || 0); - executeContextStroke(); - if (drawCrisp) { - if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); - else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); - if (lineWidth === 1) curContext.lineCap = lineCap - } - }; - Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { - if (y2 === undef || z2 === undef) { - z2 = 0; - y2 = x2; - x2 = z1; - z1 = 0 - } - if (x1 === x2 && y1 === y2 && z1 === z2) { - p.point(x1, y1, z1); - return - } - var lineVerts = [x1, y1, z1, x2, y2, z2]; - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, lineBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); - curContext.drawArrays(curContext.LINES, 0, 2) - } - }; - Drawing2D.prototype.bezier = function() { - if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1]); - p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - p.endShape() - }; - Drawing3D.prototype.bezier = function() { - if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; - p.beginShape(); - p.vertex(arguments[0], arguments[1], arguments[2]); - p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]); - p.endShape() - }; - p.bezierDetail = function(detail) { - bezDetail = detail - }; - p.bezierPoint = function(a, b, c, d, t) { - return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d - }; - p.bezierTangent = function(a, b, c, d, t) { - return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b) - }; - p.curvePoint = function(a, b, c, d, t) { - return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t) - }; - p.curveTangent = function(a, b, c, d, t) { - return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t) - }; - p.triangle = function(x1, y1, x2, y2, x3, y3) { - p.beginShape(9); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.endShape() - }; - p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { - p.beginShape(16); - p.vertex(x1, y1, 0); - p.vertex(x2, y2, 0); - p.vertex(x3, y3, 0); - p.vertex(x4, y4, 0); - p.endShape() - }; - var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { - if (bl === undef) { - tr = tl; - br = tl; - bl = tl - } - var halfWidth = width / 2, - halfHeight = height / 2; - if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); - if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); - if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); - if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); - if (!doFill || doStroke) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.moveTo(x + tl, y); - curContext.lineTo(x + width - tr, y); - curContext.quadraticCurveTo(x + width, y, x + width, y + tr); - curContext.lineTo(x + width, y + height - br); - curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); - curContext.lineTo(x + bl, y + height); - curContext.quadraticCurveTo(x, y + height, x, y + height - bl); - curContext.lineTo(x, y + tl); - curContext.quadraticCurveTo(x, y, x + tl, y); - if (!doFill || doStroke) curContext.translate(-0.5, -0.5); - executeContextFill(); - executeContextStroke() - }; - Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (!width && !height) return; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - x = Math.round(x); - y = Math.round(y); - width = Math.round(width); - height = Math.round(height); - if (tl !== undef) { - roundedRect$2d(x, y, width, height, tl, tr, br, bl); - return - } - if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); - curContext.beginPath(); - curContext.rect(x, y, width, height); - executeContextFill(); - executeContextStroke(); - if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) - }; - Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { - if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; - if (curRectMode === 1) { - width -= x; - height -= y - } else if (curRectMode === 2) { - width *= 2; - height *= 2; - x -= width / 2; - y -= height / 2 - } else if (curRectMode === 3) { - x -= width / 2; - y -= height / 2 - } - var model = new PMatrix3D; - model.translate(x, y, 0); - model.scale(width, height, 1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - if (lineWidth > 0 && doStroke) { - curContext.useProgram(programObject2D); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", strokeStyle); - uniformi("picktype2d", programObject2D, "picktype", 0); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, rectBuffer); - disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); - curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) - } - if (doFill) { - curContext.useProgram(programObject3D); - uniformMatrix("model3d", programObject3D, "model", false, model.array()); - uniformMatrix("view3d", programObject3D, "view", false, view.array()); - curContext.enable(curContext.POLYGON_OFFSET_FILL); - curContext.polygonOffset(1, 1); - uniformf("color3d", programObject3D, "color", fillStyle); - if (lightCount > 0) { - var v = new PMatrix3D; - v.set(view); - var m = new PMatrix3D; - m.set(model); - v.mult(m); - var normalMatrix = new PMatrix3D; - normalMatrix.set(v); - normalMatrix.invert(); - normalMatrix.transpose(); - uniformMatrix("normalTransform3d", programObject3D, "normalTransform", false, normalMatrix.array()); - vertexAttribPointer("normal3d", programObject3D, "Normal", 3, rectNormBuffer) - } else disableVertexAttribPointer("normal3d", programObject3D, "Normal"); - vertexAttribPointer("vertex3d", programObject3D, "Vertex", 3, rectBuffer); - curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); - curContext.disable(curContext.POLYGON_OFFSET_FILL) - } - }; - Drawing2D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - if (width === height) { - curContext.beginPath(); - curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); - executeContextFill(); - executeContextStroke() - } else { - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h); - p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y); - p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h); - p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y); - p.endShape() - } - }; - Drawing3D.prototype.ellipse = function(x, y, width, height) { - x = x || 0; - y = y || 0; - if (width <= 0 && height <= 0) return; - if (curEllipseMode === 2) { - width *= 2; - height *= 2 - } else if (curEllipseMode === 1) { - width = width - x; - height = height - y; - x += width / 2; - y += height / 2 - } else if (curEllipseMode === 0) { - x += width / 2; - y += height / 2 - } - var w = width / 2, - h = height / 2, - C = 0.5522847498307933, - c_x = C * w, - c_y = C * h; - p.beginShape(); - p.vertex(x + w, y); - p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0); - p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0); - p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0); - p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0); - p.endShape(); - if (doFill) { - var xAv = 0, - yAv = 0, - i, j; - for (i = 0; i < vertArray.length; i++) { - xAv += vertArray[i][0]; - yAv += vertArray[i][1] - } - xAv /= vertArray.length; - yAv /= vertArray.length; - var vert = [], - fillVertArray = [], - colorVertArray = []; - vert[0] = xAv; - vert[1] = yAv; - vert[2] = 0; - vert[3] = 0; - vert[4] = 0; - vert[5] = fillStyle[0]; - vert[6] = fillStyle[1]; - vert[7] = fillStyle[2]; - vert[8] = fillStyle[3]; - vert[9] = strokeStyle[0]; - vert[10] = strokeStyle[1]; - vert[11] = strokeStyle[2]; - vert[12] = strokeStyle[3]; - vert[13] = normalX; - vert[14] = normalY; - vert[15] = normalZ; - vertArray.unshift(vert); - for (i = 0; i < vertArray.length; i++) { - for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]); - for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]) - } - fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray) - } - }; - p.normal = function(nx, ny, nz) { - if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments."; - normalX = nx; - normalY = ny; - normalZ = nz; - if (curShape !== 0) if (normalMode === 0) normalMode = 1; - else if (normalMode === 1) normalMode = 2 - }; - p.save = function(file, img) { - if (img !== undef) return window.open(img.toDataURL(), "_blank"); - return window.open(p.externals.canvas.toDataURL(), "_blank") - }; - var saveNumber = 0; - p.saveFrame = function(file) { - if (file === undef) file = "screen-####.png"; - var frameFilename = file.replace(/#+/, function(all) { - var s = "" + saveNumber++; - while (s.length < all.length) s = "0" + s; - return s - }); - p.save(frameFilename) - }; - var utilityContext2d = document.createElement("canvas").getContext("2d"); - var canvasDataCache = [undef, undef, undef]; - - function getCanvasData(obj, w, h) { - var canvasData = canvasDataCache.shift(); - if (canvasData === undef) { - canvasData = {}; - canvasData.canvas = document.createElement("canvas"); - canvasData.context = canvasData.canvas.getContext("2d") - } - canvasDataCache.push(canvasData); - var canvas = canvasData.canvas, - context = canvasData.context, - width = w || obj.width, - height = h || obj.height; - canvas.width = width; - canvas.height = height; - if (!obj) context.clearRect(0, 0, width, height); - else if ("data" in obj) context.putImageData(obj, 0, 0); - else { - context.clearRect(0, 0, width, height); - context.drawImage(obj, 0, 0, width, height) - } - return canvasData - } - function buildPixelsObject(pImage) { - return { - getLength: function(aImg) { - return function() { - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; - else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 - } - }(pImage), - getPixel: function(aImg) { - return function(i) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - }(pImage), - setPixel: function(aImg) { - return function(i, c) { - var offset = i * 4, - data = aImg.imageData.data; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255; - aImg.__isDirty = true - } - }(pImage), - toArray: function(aImg) { - return function() { - var arr = [], - data = aImg.imageData.data, - length = aImg.width * aImg.height; - if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); - return arr - } - }(pImage), - set: function(aImg) { - return function(arr) { - var offset, data, c; - if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; - data = aImg.imageData.data; - for (var i = 0, aL = arr.length; i < aL; i++) { - c = arr[i]; - offset = i * 4; - data[offset + 0] = (c >> 16) & 255; - data[offset + 1] = (c >> 8) & 255; - data[offset + 2] = c & 255; - data[offset + 3] = (c >> 24) & 255 - } - aImg.__isDirty = true - } - }(pImage) - } - } - var PImage = function(aWidth, aHeight, aFormat) { - this.__isDirty = false; - if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); - else if (aHeight || aFormat) { - this.width = aWidth || 1; - this.height = aHeight || 1; - var canvas = this.sourceImg = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; - var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); - this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; - if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; - this.__isDirty = true; - this.updatePixels() - } else { - this.width = 0; - this.height = 0; - this.imageData = utilityContext2d.createImageData(1, 1); - this.format = 2 - } - this.pixels = buildPixelsObject(this) - }; - PImage.prototype = { - __isPImage: true, - updatePixels: function() { - var canvas = this.sourceImg; - if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); - this.__isDirty = false - }, - fromHTMLImageData: function(htmlImg) { - var canvasData = getCanvasData(htmlImg); - try { - var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height); - this.fromImageData(imageData) - } catch(e) { - if (htmlImg.width && htmlImg.height) { - this.isRemote = true; - this.width = htmlImg.width; - this.height = htmlImg.height - } - } - this.sourceImg = htmlImg - }, - "get": function(x, y, w, h) { - if (!arguments.length) return p.get(this); - if (arguments.length === 2) return p.get(x, y, this); - if (arguments.length === 4) return p.get(x, y, w, h, this) - }, - "set": function(x, y, c) { - p.set(x, y, c, this); - this.__isDirty = true - }, - blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) { - if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this); - else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this); - delete this.sourceImg - }, - copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) { - if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this); - else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); - delete this.sourceImg - }, - filter: function(mode, param) { - if (arguments.length === 2) p.filter(mode, param, this); - else if (arguments.length === 1) p.filter(mode, null, this); - delete this.sourceImg - }, - save: function(file) { - p.save(file, this) - }, - resize: function(w, h) { - if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; - if (this.width !== 0 || this.height !== 0) { - if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h); - else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w); - var canvas = getCanvasData(this.imageData).canvas; - var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h); - this.fromImageData(imageData) - } - }, - mask: function(mask) { - var obj = this.toImageData(), - i, size; - if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { - mask = mask.toImageData(); - for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] - } else throw "mask must have the same dimensions as PImage."; - else if (mask instanceof - Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; - else throw "mask array must be the same length as PImage pixels array."; - this.fromImageData(obj) - }, - loadPixels: nop, - toImageData: function() { - if (this.isRemote) return this.sourceImg; - if (!this.__isDirty) return this.imageData; - var canvasData = getCanvasData(this.imageData); - return canvasData.context.getImageData(0, 0, this.width, this.height) - }, - toDataURL: function() { - if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; - var canvasData = getCanvasData(this.imageData); - return canvasData.canvas.toDataURL() - }, - fromImageData: function(canvasImg) { - var w = canvasImg.width, - h = canvasImg.height, - canvas = document.createElement("canvas"), - ctx = canvas.getContext("2d"); - this.width = canvas.width = w; - this.height = canvas.height = h; - ctx.putImageData(canvasImg, 0, 0); - this.format = 2; - this.imageData = canvasImg; - this.sourceImg = canvas - } - }; - p.PImage = PImage; - p.createImage = function(w, h, mode) { - return new PImage(w, h, mode) - }; - p.loadImage = function(file, type, callback) { - if (type) file = file + "." + type; - var pimg; - if (curSketch.imageCache.images[file]) { - pimg = new PImage(curSketch.imageCache.images[file]); - pimg.loaded = true; - return pimg - } - pimg = new PImage; - var img = document.createElement("img"); - pimg.sourceImg = img; - img.onload = function(aImage, aPImage, aCallback) { - var image = aImage; - var pimg = aPImage; - var callback = aCallback; - return function() { - pimg.fromHTMLImageData(image); - pimg.loaded = true; - if (callback) callback() - } - }(img, pimg, callback); - img.src = file; - return pimg - }; - p.requestImage = p.loadImage; - - function get$2(x, y) { - var data; - if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; - if (isContextReplaced) { - var offset = ((0 | x) + p.width * (0 | y)) * 4; - data = p.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - data = p.toImageData(0 | x, 0 | y, 1, 1).data; - return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 - } - function get$3(x, y, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; - var offset = y * img.width * 4 + x * 4, - data = img.imageData.data; - return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 - } - function get$4(x, y, w, h) { - var c = new PImage(w, h, 2); - c.fromImageData(p.toImageData(x, y, w, h)); - return c - } - function get$5(x, y, w, h, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h."; - var c = new PImage(w, h, 2), - cData = c.imageData.data, - imgWidth = img.width, - imgHeight = img.height, - imgData = img.imageData.data; - var startRow = Math.max(0, -y), - startColumn = Math.max(0, -x), - stopRow = Math.min(h, imgHeight - y), - stopColumn = Math.min(w, imgWidth - x); - for (var i = startRow; i < stopRow; ++i) { - var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4; - var targetOffset = (i * w + startColumn) * 4; - for (var j = startColumn; j < stopColumn; ++j) { - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++]; - cData[targetOffset++] = imgData[sourceOffset++] - } - } - c.__isDirty = true; - return c - } - p.get = function(x, y, w, h, img) { - if (img !== undefined) return get$5(x, y, w, h, img); - if (h !== undefined) return get$4(x, y, w, h); - if (w !== undefined) return get$3(x, y, w); - if (y !== undefined) return get$2(x, y); - if (x !== undefined) return get$5(0, 0, x.width, x.height, x); - return get$4(0, 0, p.width, p.height) - }; - p.createGraphics = function(w, h, render) { - var pg = new Processing; - pg.size(w, h, render); - return pg - }; - - function resetContext() { - if (isContextReplaced) { - curContext = originalContext; - isContextReplaced = false; - p.updatePixels() - } - } - function SetPixelContextWrapper() { - function wrapFunction(newContext, name) { - function wrapper() { - resetContext(); - curContext[name].apply(curContext, arguments) - } - newContext[name] = wrapper - } - function wrapProperty(newContext, name) { - function getter() { - resetContext(); - return curContext[name] - } - function setter(value) { - resetContext(); - curContext[name] = value - } - p.defineProperty(newContext, name, { - get: getter, - set: setter - }) - } - for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n); - else wrapProperty(this, n) - } - function replaceContext() { - if (isContextReplaced) return; - p.loadPixels(); - if (proxyContext === null) { - originalContext = curContext; - proxyContext = new SetPixelContextWrapper - } - isContextReplaced = true; - curContext = proxyContext; - setPixelsCached = 0 - } - function set$3(x, y, c) { - if (x < p.width && x >= 0 && y >= 0 && y < p.height) { - replaceContext(); - p.pixels.setPixel((0 | x) + p.width * (0 | y), c); - if (++setPixelsCached > maxPixelsCached) resetContext() - } - } - function set$4(x, y, obj, img) { - if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y."; - var c = p.color.toArray(obj); - var offset = y * img.width * 4 + x * 4; - var data = img.imageData.data; - data[offset] = c[0]; - data[offset + 1] = c[1]; - data[offset + 2] = c[2]; - data[offset + 3] = c[3] - } - p.set = function(x, y, obj, img) { - var color, oldFill; - if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj); - else { - if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y) - } else if (arguments.length === 4) set$4(x, y, obj, img) - }; - p.imageData = {}; - p.pixels = { - getLength: function() { - return p.imageData.data.length ? p.imageData.data.length / 4 : 0 - }, - getPixel: function(i) { - var offset = i * 4, - data = p.imageData.data; - return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 - }, - setPixel: function(i, c) { - var offset = i * 4, - data = p.imageData.data; - data[offset + 0] = (c & 16711680) >>> 16; - data[offset + 1] = (c & 65280) >>> 8; - data[offset + 2] = c & 255; - data[offset + 3] = (c & 4278190080) >>> 24 - }, - toArray: function() { - var arr = [], - length = p.imageData.width * p.imageData.height, - data = p.imageData.data; - for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); - return arr - }, - set: function(arr) { - for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) - } - }; - p.loadPixels = function() { - p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) - }; - p.updatePixels = function() { - if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) - }; - p.hint = function(which) { - var curContext = drawing.$ensureContext(); - if (which === 4) { - curContext.disable(curContext.DEPTH_TEST); - curContext.depthMask(false); - curContext.clear(curContext.DEPTH_BUFFER_BIT) - } else if (which === -4) { - curContext.enable(curContext.DEPTH_TEST); - curContext.depthMask(true) - } - }; - var backgroundHelper = function(arg1, arg2, arg3, arg4) { - var obj; - if (arg1 instanceof PImage || arg1.__isPImage) { - obj = arg1; - if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; - if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; - } else obj = p.color(arg1, arg2, arg3, arg4); - backgroundObj = obj - }; - Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); - if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - p.image(backgroundObj, 0, 0); - restoreContext() - } else { - saveContext(); - curContext.setTransform(1, 0, 0, 1, 0, 0); - if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); - curContext.fillStyle = p.color.toString(backgroundObj); - curContext.fillRect(0, 0, p.width, p.height); - isFillDirty = true; - restoreContext() - } - }; - Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { - if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); - var c = p.color.toGLArray(backgroundObj); - curContext.clearColor(c[0], c[1], c[2], c[3]); - curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) - }; - Drawing2D.prototype.image = function(img, x, y, w, h) { - x = Math.round(x); - y = Math.round(y); - if (img.width > 0) { - var wid = w || img.width; - var hgt = h || img.height; - var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); - var fastImage = !!img.sourceImg && curTint === null; - if (fastImage) { - var htmlElement = img.sourceImg; - if (img.__isDirty) img.updatePixels(); - curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) - } else { - var obj = img.toImageData(); - if (curTint !== null) { - curTint(obj); - img.__isDirty = true - } - curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) - } - } - }; - Drawing3D.prototype.image = function(img, x, y, w, h) { - if (img.width > 0) { - x = Math.round(x); - y = Math.round(y); - w = w || img.width; - h = h || img.height; - p.beginShape(p.QUADS); - p.texture(img); - p.vertex(x, y, 0, 0, 0); - p.vertex(x, y + h, 0, 0, h); - p.vertex(x + w, y + h, 0, w, h); - p.vertex(x + w, y, 0, w, 0); - p.endShape() - } - }; - p.tint = function(a1, a2, a3, a4) { - var tintColor = p.color(a1, a2, a3, a4); - var r = p.red(tintColor) / colorModeX; - var g = p.green(tintColor) / colorModeY; - var b = p.blue(tintColor) / colorModeZ; - var a = p.alpha(tintColor) / colorModeA; - curTint = function(obj) { - var data = obj.data, - length = 4 * obj.width * obj.height; - for (var i = 0; i < length;) { - data[i++] *= r; - data[i++] *= g; - data[i++] *= b; - data[i++] *= a - } - }; - curTint3d = function(data) { - for (var i = 0; i < data.length;) { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a - } - } - }; - p.noTint = function() { - curTint = null; - curTint3d = null - }; - p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { - if (dh === undef) { - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0) - }; - p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { - if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; - if (mode === undef) { - mode = dh; - dh = dw; - dw = dy; - dy = dx; - dx = sh; - sh = sw; - sw = sy; - sy = sx; - sx = src; - src = p - } - var sx2 = sx + sw, - sy2 = sy + sh, - dx2 = dx + dw, - dy2 = dy + dh, - dest = pimgdest || p; - if (pimgdest === undef || mode === undef) p.loadPixels(); - src.loadPixels(); - if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode); - if (pimgdest === undef) p.updatePixels() - }; - var buildBlurKernel = function(r) { - var radius = p.floor(r * 3.5), - i, radiusi; - radius = radius < 1 ? 1 : radius < 248 ? radius : 248; - if (p.shared.blurRadius !== radius) { - p.shared.blurRadius = radius; - p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1); - p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize); - var sharedBlurKernal = p.shared.blurKernel; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; - var radiusiSquared = (radius - 1) * (radius - 1); - for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; - sharedBlurKernal[radius] = radius * radius - } - }; - var blurARGB = function(r, aImg) { - var sum, cr, cg, cb, ca, c, m; - var read, ri, ym, ymi, bk0; - var wh = aImg.pixels.getLength(); - var r2 = new Float32Array(wh); - var g2 = new Float32Array(wh); - var b2 = new Float32Array(wh); - var a2 = new Float32Array(wh); - var yi = 0; - var x, y, i, offset; - buildBlurKernel(r); - var aImgHeight = aImg.height; - var aImgWidth = aImg.width; - var sharedBlurKernelSize = p.shared.blurKernelSize; - var sharedBlurRadius = p.shared.blurRadius; - var sharedBlurKernal = p.shared.blurKernel; - var pix = aImg.imageData.data; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - read = x - sharedBlurRadius; - if (read < 0) { - bk0 = -read; - read = 0 - } else { - if (read >= aImgWidth) break; - bk0 = 0 - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (read >= aImgWidth) break; - offset = (read + yi) * 4; - m = sharedBlurKernal[i]; - ca += m * pix[offset + 3]; - cr += m * pix[offset]; - cg += m * pix[offset + 1]; - cb += m * pix[offset + 2]; - sum += m; - read++ - } - ri = yi + x; - a2[ri] = ca / sum; - r2[ri] = cr / sum; - g2[ri] = cg / sum; - b2[ri] = cb / sum - } - yi += aImgWidth - } - yi = 0; - ym = -sharedBlurRadius; - ymi = ym * aImgWidth; - for (y = 0; y < aImgHeight; y++) { - for (x = 0; x < aImgWidth; x++) { - cb = cg = cr = ca = sum = 0; - if (ym < 0) { - bk0 = ri = -ym; - read = x - } else { - if (ym >= aImgHeight) break; - bk0 = 0; - ri = ym; - read = x + ymi - } - for (i = bk0; i < sharedBlurKernelSize; i++) { - if (ri >= aImgHeight) break; - m = sharedBlurKernal[i]; - ca += m * a2[read]; - cr += m * r2[read]; - cg += m * g2[read]; - cb += m * b2[read]; - sum += m; - ri++; - read += aImgWidth - } - offset = (x + yi) * 4; - pix[offset] = cr / sum; - pix[offset + 1] = cg / sum; - pix[offset + 2] = cb / sum; - pix[offset + 3] = ca / sum - } - yi += aImgWidth; - ymi += aImgWidth; - ym++ - } - }; - var dilate = function(isInverted, aImg) { - var currIdx = 0; - var maxIdx = aImg.pixels.getLength(); - var out = new Int32Array(maxIdx); - var currRowIdx, maxRowIdx, colOrig, colOut, currLum; - var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown; - if (!isInverted) while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft > currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight > currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp > currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown > currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } else while (currIdx < maxIdx) { - currRowIdx = currIdx; - maxRowIdx = currIdx + aImg.width; - while (currIdx < maxRowIdx) { - colOrig = colOut = aImg.pixels.getPixel(currIdx); - idxLeft = currIdx - 1; - idxRight = currIdx + 1; - idxUp = currIdx - aImg.width; - idxDown = currIdx + aImg.width; - if (idxLeft < currRowIdx) idxLeft = currIdx; - if (idxRight >= maxRowIdx) idxRight = currIdx; - if (idxUp < 0) idxUp = 0; - if (idxDown >= maxIdx) idxDown = currIdx; - colUp = aImg.pixels.getPixel(idxUp); - colLeft = aImg.pixels.getPixel(idxLeft); - colDown = aImg.pixels.getPixel(idxDown); - colRight = aImg.pixels.getPixel(idxRight); - currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255); - lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255); - lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255); - lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255); - lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255); - if (lumLeft < currLum) { - colOut = colLeft; - currLum = lumLeft - } - if (lumRight < currLum) { - colOut = colRight; - currLum = lumRight - } - if (lumUp < currLum) { - colOut = colUp; - currLum = lumUp - } - if (lumDown < currLum) { - colOut = colDown; - currLum = lumDown - } - out[currIdx++] = colOut - } - } - aImg.pixels.set(out) - }; - p.filter = function(kind, param, aImg) { - var img, col, lum, i; - if (arguments.length === 3) { - aImg.loadPixels(); - img = aImg - } else { - p.loadPixels(); - img = p - } - if (param === undef) param = null; - if (img.isRemote) throw "Image is loaded remotely. Cannot filter image."; - var imglen = img.pixels.getLength(); - switch (kind) { - case 11: - var radius = param || 1; - blurARGB(radius, img); - break; - case 12: - if (img.format === 4) { - for (i = 0; i < imglen; i++) { - col = 255 - img.pixels.getPixel(i); - img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) - } - img.format = 1 - } else for (i = 0; i < imglen; i++) { - col = img.pixels.getPixel(i); - lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8; - img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum) - } - break; - case 13: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); - break; - case 15: - if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"; - var levels = p.floor(param); - if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)"; - var levels1 = levels - 1; - for (i = 0; i < imglen; i++) { - var rlevel = img.pixels.getPixel(i) >> 16 & 255; - var glevel = img.pixels.getPixel(i) >> 8 & 255; - var blevel = img.pixels.getPixel(i) & 255; - rlevel = (rlevel * levels >> 8) * 255 / levels1; - glevel = (glevel * levels >> 8) * 255 / levels1; - blevel = (blevel * levels >> 8) * 255 / levels1; - img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel) - } - break; - case 14: - for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); - img.format = 1; - break; - case 16: - if (param === null) param = 0.5; - if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)"; - var thresh = p.floor(param * 255); - for (i = 0; i < imglen; i++) { - var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); - img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) - } - break; - case 17: - dilate(true, img); - break; - case 18: - dilate(false, img); - break - } - img.updatePixels() - }; - p.shared = { - fracU: 0, - ifU: 0, - fracV: 0, - ifV: 0, - u1: 0, - u2: 0, - v1: 0, - v2: 0, - sX: 0, - sY: 0, - iw: 0, - iw1: 0, - ih1: 0, - ul: 0, - ll: 0, - ur: 0, - lr: 0, - cUL: 0, - cLL: 0, - cUR: 0, - cLR: 0, - srcXOffset: 0, - srcYOffset: 0, - r: 0, - g: 0, - b: 0, - a: 0, - srcBuffer: null, - blurRadius: 0, - blurKernelSize: 0, - blurKernel: null - }; - p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { - var sw = sx2 - sx1 + 1; - var sh = sy2 - sy1 + 1; - var dw = dx2 - dx1 + 1; - var dh = dy2 - dy1 + 1; - if (dx1 < sx1) { - dw += dx1 - sx1; - if (dw > sw) dw = sw - } else { - var w = sw + sx1 - dx1; - if (dw > w) dw = w - } - if (dy1 < sy1) { - dh += dy1 - sy1; - if (dh > sh) dh = sh - } else { - var h = sh + sy1 - dy1; - if (dh > h) dh = h - } - return ! (dw <= 0 || dh <= 0) - }; - var blendFuncs = {}; - blendFuncs[1] = p.modes.blend; - blendFuncs[2] = p.modes.add; - blendFuncs[4] = p.modes.subtract; - blendFuncs[8] = p.modes.lightest; - blendFuncs[16] = p.modes.darkest; - blendFuncs[0] = p.modes.replace; - blendFuncs[32] = p.modes.difference; - blendFuncs[64] = p.modes.exclusion; - blendFuncs[128] = p.modes.multiply; - blendFuncs[256] = p.modes.screen; - blendFuncs[512] = p.modes.overlay; - blendFuncs[1024] = p.modes.hard_light; - blendFuncs[2048] = p.modes.soft_light; - blendFuncs[4096] = p.modes.dodge; - blendFuncs[8192] = p.modes.burn; - p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { - var x, y; - if (srcX1 < 0) srcX1 = 0; - if (srcY1 < 0) srcY1 = 0; - if (srcX2 >= img.width) srcX2 = img.width - 1; - if (srcY2 >= img.height) srcY2 = img.height - 1; - var srcW = srcX2 - srcX1; - var srcH = srcY2 - srcY1; - var destW = destX2 - destX1; - var destH = destY2 - destY1; - if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return; - var dx = Math.floor(srcW / destW * 32768); - var dy = Math.floor(srcH / destH * 32768); - var pshared = p.shared; - pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); - pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); - if (destX1 < 0) { - destW += destX1; - destX1 = 0 - } - if (destY1 < 0) { - destH += destY1; - destY1 = 0 - } - destW = Math.min(destW, screenW - destX1); - destH = Math.min(destH, screenH - destY1); - var destOffset = destY1 * screenW + destX1; - var destColor; - pshared.srcBuffer = img.imageData.data; - pshared.iw = img.width; - pshared.iw1 = img.width - 1; - pshared.ih1 = img.height - 1; - var filterBilinear = p.filter_bilinear, - filterNewScanline = p.filter_new_scanline, - blendFunc = blendFuncs[mode], - blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, - RED_MASK = 16711680, - GREEN_MASK = 65280, - BLUE_MASK = 255, - PREC_MAXVAL = 32767, - PRECISIONB = 15, - PREC_RED_SHIFT = 1, - PREC_ALPHA_SHIFT = 9, - srcBuffer = pshared.srcBuffer, - min = Math.min; - for (y = 0; y < destH; y++) { - pshared.sX = pshared.srcXOffset; - pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; - pshared.ifV = PREC_MAXVAL - pshared.fracV; - pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; - pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; - for (x = 0; x < destW; x++) { - idx = (destOffset + x) * 4; - destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; - pshared.fracU = pshared.sX & PREC_MAXVAL; - pshared.ifU = PREC_MAXVAL - pshared.fracU; - pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; - pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; - pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; - pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; - pshared.u1 = pshared.sX >> PRECISIONB; - pshared.u2 = min(pshared.u1 + 1, pshared.iw1); - cULoffset = (pshared.v1 + pshared.u1) * 4; - cURoffset = (pshared.v1 + pshared.u2) * 4; - cLLoffset = (pshared.v2 + pshared.u1) * 4; - cLRoffset = (pshared.v2 + pshared.u2) * 4; - pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; - pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; - pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; - pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; - pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; - pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; - pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; - pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; - blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); - destPixels[idx] = (blendedColor & RED_MASK) >>> 16; - destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; - destPixels[idx + 2] = blendedColor & BLUE_MASK; - destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; - pshared.sX += dx - } - destOffset += screenW; - pshared.srcYOffset += dy - } - }; - p.loadFont = function(name, size) { - if (name === undef) throw "font name required in loadFont."; - if (name.indexOf(".svg") === -1) { - if (size === undef) size = curTextFont.size; - return PFont.get(name, size) - } - var font = p.loadGlyphs(name); - return { - name: name, - css: "12px sans-serif", - glyph: true, - units_per_em: font.units_per_em, - horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x, - ascent: font.ascent, - descent: font.descent, - width: function(str) { - var width = 0; - var len = str.length; - for (var i = 0; i < len; i++) try { - width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x) - } catch(e) { - Processing.debug(e) - } - return width / p.glyphTable[name].units_per_em - } - } - }; - p.createFont = function(name, size) { - return p.loadFont(name, size) - }; - p.textFont = function(pfont, size) { - if (size !== undef) { - if (!pfont.glyph) pfont = PFont.get(pfont.name, size); - curTextSize = size - } - curTextFont = pfont; - curFontName = curTextFont.name; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - }; - p.textSize = function(size) { - if (size !== curTextSize) { - curTextFont = PFont.get(curFontName, size); - curTextSize = size; - curTextAscent = curTextFont.ascent; - curTextDescent = curTextFont.descent; - curTextLeading = curTextFont.leading; - var curContext = drawing.$ensureContext(); - curContext.font = curTextFont.css - } - }; - p.textAscent = function() { - return curTextAscent - }; - p.textDescent = function() { - return curTextDescent - }; - p.textLeading = function(leading) { - curTextLeading = leading - }; - p.textAlign = function(xalign, yalign) { - horizontalTextAlignment = xalign; - verticalTextAlignment = yalign || 0 - }; - - function toP5String(obj) { - if (obj instanceof String) return obj; - if (typeof obj === "number") { - if (obj === (0 | obj)) return obj.toString(); - return p.nf(obj, 0, 3) - } - if (obj === null || obj === undef) return ""; - return obj.toString() - } - Drawing2D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - curContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); - return width | 0 - }; - Drawing3D.prototype.textWidth = function(str) { - var lines = toP5String(str).split(/\r?\n/g), - width = 0; - var i, linesCount = lines.length; - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var textContext = textcanvas.getContext("2d"); - textContext.font = curTextFont.css; - for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); - return width | 0 - }; - p.glyphLook = function(font, chr) { - try { - switch (chr) { - case "1": - return font.one; - case "2": - return font.two; - case "3": - return font.three; - case "4": - return font.four; - case "5": - return font.five; - case "6": - return font.six; - case "7": - return font.seven; - case "8": - return font.eight; - case "9": - return font.nine; - case "0": - return font.zero; - case " ": - return font.space; - case "$": - return font.dollar; - case "!": - return font.exclam; - case '"': - return font.quotedbl; - case "#": - return font.numbersign; - case "%": - return font.percent; - case "&": - return font.ampersand; - case "'": - return font.quotesingle; - case "(": - return font.parenleft; - case ")": - return font.parenright; - case "*": - return font.asterisk; - case "+": - return font.plus; - case ",": - return font.comma; - case "-": - return font.hyphen; - case ".": - return font.period; - case "/": - return font.slash; - case "_": - return font.underscore; - case ":": - return font.colon; - case ";": - return font.semicolon; - case "<": - return font.less; - case "=": - return font.equal; - case ">": - return font.greater; - case "?": - return font.question; - case "@": - return font.at; - case "[": - return font.bracketleft; - case "\\": - return font.backslash; - case "]": - return font.bracketright; - case "^": - return font.asciicircum; - case "`": - return font.grave; - case "{": - return font.braceleft; - case "|": - return font.bar; - case "}": - return font.braceright; - case "~": - return font.asciitilde; - default: - return font[chr] - } - } catch(e) { - Processing.debug(e) - } - }; - Drawing2D.prototype.text$line = function(str, x, y, z, align) { - var textWidth = 0, - xOffset = 0; - if (!curTextFont.glyph) { - if (str && "fillText" in curContext) { - if (isFillDirty) { - curContext.fillStyle = p.color.toString(currentFillColor); - isFillDirty = false - } - if (align === 39 || align === 3) { - textWidth = curTextFont.measureTextWidth(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - curContext.fillText(str, x + xOffset, y) - } - } else { - var font = p.glyphTable[curFontName]; - saveContext(); - curContext.translate(x, y + curTextSize); - if (align === 39 || align === 3) { - textWidth = font.width(str); - if (align === 39) xOffset = -textWidth; - else xOffset = -textWidth / 2 - } - var upem = font.units_per_em, - newScale = 1 / upem * curTextSize; - curContext.scale(newScale, newScale); - for (var i = 0, len = str.length; i < len; i++) try { - p.glyphLook(font, str[i]).draw() - } catch(e) { - Processing.debug(e) - } - restoreContext() - } - }; - Drawing3D.prototype.text$line = function(str, x, y, z, align) { - if (textcanvas === undef) textcanvas = document.createElement("canvas"); - var oldContext = curContext; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - var textWidth = curTextFont.measureTextWidth(str); - textcanvas.width = textWidth; - textcanvas.height = curTextSize; - curContext = textcanvas.getContext("2d"); - curContext.font = curTextFont.css; - curContext.textBaseline = "top"; - Drawing2D.prototype.text$line(str, 0, 0, 0, 37); - var aspect = textcanvas.width / textcanvas.height; - curContext = oldContext; - curContext.bindTexture(curContext.TEXTURE_2D, textTex); - curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE); - curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE); - var xOffset = 0; - if (align === 39) xOffset = -textWidth; - else if (align === 3) xOffset = -textWidth / 2; - var model = new PMatrix3D; - var scalefactor = curTextSize * 0.5; - model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z); - model.scale(-aspect * scalefactor, -scalefactor, scalefactor); - model.translate(-1, -1, -1); - model.transpose(); - var view = new PMatrix3D; - view.scale(1, -1, 1); - view.apply(modelView.array()); - view.transpose(); - curContext.useProgram(programObject2D); - vertexAttribPointer("vertex2d", programObject2D, "Vertex", 3, textBuffer); - vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); - uniformi("uSampler2d", programObject2D, "uSampler", [0]); - uniformi("picktype2d", programObject2D, "picktype", 1); - uniformMatrix("model2d", programObject2D, "model", false, model.array()); - uniformMatrix("view2d", programObject2D, "view", false, view.array()); - uniformf("color2d", programObject2D, "color", fillStyle); - curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer); - curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0) - }; - - function text$4(str, x, y, z) { - var lines, linesCount; - if (str.indexOf("\n") < 0) { - lines = [str]; - linesCount = 1 - } else { - lines = str.split(/\r?\n/g); - linesCount = lines.length - } - var yOffset = 0; - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; - else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); - for (var i = 0; i < linesCount; ++i) { - var line = lines[i]; - drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); - yOffset += curTextLeading - } - } - function text$6(str, x, y, width, height, z) { - if (str.length === 0 || width === 0 || height === 0) return; - if (curTextSize > height) return; - var spaceMark = -1; - var start = 0; - var lineWidth = 0; - var drawCommands = []; - for (var charPos = 0, len = str.length; charPos < len; charPos++) { - var currentChar = str[charPos]; - var spaceChar = currentChar === " "; - var letterWidth = curTextFont.measureTextWidth(currentChar); - if (currentChar !== "\n" && lineWidth + letterWidth <= width) { - if (spaceChar) spaceMark = charPos; - lineWidth += letterWidth - } else { - if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; - else return; - if (currentChar === "\n") { - drawCommands.push({ - text: str.substring(start, charPos), - width: lineWidth - }); - start = charPos + 1 - } else { - drawCommands.push({ - text: str.substring(start, spaceMark + 1), - width: lineWidth - }); - start = spaceMark + 1 - } - lineWidth = 0; - charPos = start - 1 - } - } - if (start < len) drawCommands.push({ - text: str.substring(start), - width: lineWidth - }); - var xOffset = 1, - yOffset = curTextAscent; - if (horizontalTextAlignment === 3) xOffset = width / 2; - else if (horizontalTextAlignment === 39) xOffset = width; - var linesCount = drawCommands.length, - visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); - if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; - else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); - else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; - var command, drawCommand, leading; - for (command = 0; command < linesCount; command++) { - leading = command * curTextLeading; - if (yOffset + leading > height - curTextDescent) break; - drawCommand = drawCommands[command]; - drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) - } - } - p.text = function() { - if (textMode === 5) return; - if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0); - else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]); - else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0); - else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) - }; - p.textMode = function(mode) { - textMode = mode - }; - p.loadGlyphs = function(url) { - var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", - path; - var regex = function(needle, hay) { - var i = 0, - results = [], - latest, regexp = new RegExp(needle, "g"); - latest = results[i] = regexp.exec(hay); - while (latest) { - i++; - latest = results[i] = regexp.exec(hay) - } - return results - }; - var buildPath = function(d) { - var c = regex("[A-Za-z][0-9\\- ]+|Z", d); - var beforePathDraw = function() { - saveContext(); - return drawing.$ensureContext() - }; - var afterPathDraw = function() { - executeContextFill(); - executeContextStroke(); - restoreContext() - }; - path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();"; - x = 0; - y = 0; - cx = 0; - cy = 0; - nx = 0; - ny = 0; - d = 0; - a = 0; - lastCom = ""; - lenC = c.length - 1; - for (var j = 0; j < lenC; j++) { - var com = c[j][0], - xy = regex(getXY, com); - switch (com[0]) { - case "M": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.moveTo(" + x + "," + -y + ");"; - break; - case "L": - x = parseFloat(xy[0][0]); - y = parseFloat(xy[1][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "H": - x = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "V": - y = parseFloat(xy[0][0]); - path += "curContext.lineTo(" + x + "," + -y + ");"; - break; - case "T": - nx = parseFloat(xy[0][0]); - ny = parseFloat(xy[1][0]); - if (lastCom === "Q" || lastCom === "T") { - d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2)); - a = Math.PI + Math.atan2(cx - x, cy - y); - cx = x + Math.sin(a) * d; - cy = y + Math.cos(a) * d - } else { - cx = x; - cy = y - } - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Q": - cx = parseFloat(xy[0][0]); - cy = parseFloat(xy[1][0]); - nx = parseFloat(xy[2][0]); - ny = parseFloat(xy[3][0]); - path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");"; - x = nx; - y = ny; - break; - case "Z": - path += "curContext.closePath();"; - break - } - lastCom = com[0] - } - path += "afterPathDraw();"; - path += "curContext.translate(" + horiz_adv_x + ",0);"; - path += "}}"; - return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) - }; - var parseSVGFont = function(svg) { - var font = svg.getElementsByTagName("font"); - p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x"); - var font_face = svg.getElementsByTagName("font-face")[0]; - p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em")); - p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent")); - p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent")); - var glyph = svg.getElementsByTagName("glyph"), - len = glyph.length; - for (var i = 0; i < len; i++) { - var unicode = glyph[i].getAttribute("unicode"); - var name = glyph[i].getAttribute("glyph-name"); - horiz_adv_x = glyph[i].getAttribute("horiz-adv-x"); - if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x; - d = glyph[i].getAttribute("d"); - if (d !== undef) { - path = buildPath(d); - p.glyphTable[url][name] = { - name: name, - unicode: unicode, - horiz_adv_x: horiz_adv_x, - draw: path.draw - } - } - } - }; - var loadXML = function() { - var xmlDoc; - try { - xmlDoc = document.implementation.createDocument("", "", null) - } catch(e_fx_op) { - Processing.debug(e_fx_op.message); - return - } - try { - xmlDoc.async = false; - xmlDoc.load(url); - parseSVGFont(xmlDoc.getElementsByTagName("svg")[0]) - } catch(e_sf_ch) { - Processing.debug(e_sf_ch); - try { - var xmlhttp = new window.XMLHttpRequest; - xmlhttp.open("GET", url, false); - xmlhttp.send(null); - parseSVGFont(xmlhttp.responseXML.documentElement) - } catch(e) { - Processing.debug(e_sf_ch) - } - } - }; - p.glyphTable[url] = {}; - loadXML(url); - return p.glyphTable[url] - }; - p.param = function(name) { - var attributeName = "data-processing-" + name; - if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); - for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { - var item = curElement.childNodes.item(i); - if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; - if (item.getAttribute("name") === name) return item.getAttribute("value") - } - if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; - return null - }; - - function wireDimensionalFunctions(mode) { - if (mode === "3D") drawing = new Drawing3D; - else if (mode === "2D") drawing = new Drawing2D; - else drawing = new DrawingPre; - for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; - drawing.$init() - } - function createDrawingPreFunction(name) { - return function() { - wireDimensionalFunctions("2D"); - return drawing[name].apply(this, arguments) - } - } - DrawingPre.prototype.translate = createDrawingPreFunction("translate"); - DrawingPre.prototype.scale = createDrawingPreFunction("scale"); - DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); - DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); - DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); - DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); - DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); - DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); - DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); - DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); - DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); - DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); - DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); - DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); - DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); - DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); - DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); - DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); - DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); - DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); - DrawingPre.prototype.box = createDrawingPreFunction("box"); - DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); - DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); - DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); - DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); - DrawingPre.prototype.specular = createDrawingPreFunction("specular"); - DrawingPre.prototype.fill = createDrawingPreFunction("fill"); - DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); - DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); - DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); - DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); - DrawingPre.prototype.point = createDrawingPreFunction("point"); - DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); - DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); - DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); - DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); - DrawingPre.prototype.curve = createDrawingPreFunction("curve"); - DrawingPre.prototype.line = createDrawingPreFunction("line"); - DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); - DrawingPre.prototype.rect = createDrawingPreFunction("rect"); - DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); - DrawingPre.prototype.background = createDrawingPreFunction("background"); - DrawingPre.prototype.image = createDrawingPreFunction("image"); - DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); - DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); - DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); - DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); - DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { - wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); - p.size(aWidth, aHeight, aMode) - }; - DrawingPre.prototype.$init = nop; - Drawing2D.prototype.$init = function() { - p.size(p.width, p.height); - curContext.lineCap = "round"; - p.noSmooth(); - p.disableContextMenu() - }; - Drawing3D.prototype.$init = function() { - p.use3DContext = true - }; - DrawingShared.prototype.$ensureContext = function() { - return curContext - }; - - function calculateOffset(curElement, event) { - var element = curElement, - offsetX = 0, - offsetY = 0; - p.pmouseX = p.mouseX; - p.pmouseY = p.mouseY; - if (element.offsetParent) { - do { - offsetX += element.offsetLeft; - offsetY += element.offsetTop - } while ( !! (element = element.offsetParent)) - } - element = curElement; - do { - offsetX -= element.scrollLeft || 0; - offsetY -= element.scrollTop || 0 - } while ( !! (element = element.parentNode)); - offsetX += stylePaddingLeft; - offsetY += stylePaddingTop; - offsetX += styleBorderLeft; - offsetY += styleBorderTop; - offsetX += window.pageXOffset; - offsetY += window.pageYOffset; - return { - "X": offsetX, - "Y": offsetY - } - } - function updateMousePosition(curElement, event) { - var offset = calculateOffset(curElement, event); - p.mouseX = event.pageX - offset.X; - p.mouseY = event.pageY - offset.Y - } - function addTouchEventOffset(t) { - var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), - i; - for (i = 0; i < t.touches.length; i++) { - var touch = t.touches[i]; - touch.offsetX = touch.pageX - offset.X; - touch.offsetY = touch.pageY - offset.Y - } - for (i = 0; i < t.targetTouches.length; i++) { - var targetTouch = t.targetTouches[i]; - targetTouch.offsetX = targetTouch.pageX - offset.X; - targetTouch.offsetY = targetTouch.pageY - offset.Y - } - for (i = 0; i < t.changedTouches.length; i++) { - var changedTouch = t.changedTouches[i]; - changedTouch.offsetX = changedTouch.pageX - offset.X; - changedTouch.offsetY = changedTouch.pageY - offset.Y - } - return t - } - attachEventHandler(curElement, "touchstart", function(t) { - curElement.setAttribute("style", "-webkit-user-select: none"); - curElement.setAttribute("onclick", "void(0)"); - curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); - for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { - var type = eventHandlers[i].type; - if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) - } - if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { - attachEventHandler(curElement, "touchstart", function(t) { - if (p.touchStart !== undef) { - t = addTouchEventOffset(t); - p.touchStart(t) - } - }); - attachEventHandler(curElement, "touchmove", function(t) { - if (p.touchMove !== undef) { - t.preventDefault(); - t = addTouchEventOffset(t); - p.touchMove(t) - } - }); - attachEventHandler(curElement, "touchend", function(t) { - if (p.touchEnd !== undef) { - t = addTouchEventOffset(t); - p.touchEnd(t) - } - }); - attachEventHandler(curElement, "touchcancel", function(t) { - if (p.touchCancel !== undef) { - t = addTouchEventOffset(t); - p.touchCancel(t) - } - }) - } else { - attachEventHandler(curElement, "touchstart", function(e) { - updateMousePosition(curElement, e.touches[0]); - p.__mousePressed = true; - p.mouseDragging = false; - p.mouseButton = 37; - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "touchmove", function(e) { - e.preventDefault(); - updateMousePosition(curElement, e.touches[0]); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "touchend", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }) - } - curElement.dispatchEvent(t) - }); - (function() { - var enabled = true, - contextMenu = function(e) { - e.preventDefault(); - e.stopPropagation() - }; - p.disableContextMenu = function() { - if (!enabled) return; - attachEventHandler(curElement, "contextmenu", contextMenu); - enabled = false - }; - p.enableContextMenu = function() { - if (enabled) return; - detachEventHandler({ - elem: curElement, - type: "contextmenu", - fn: contextMenu - }); - enabled = true - } - })(); - attachEventHandler(curElement, "mousemove", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); - if (typeof p.mouseDragged === "function" && p.__mousePressed) { - p.mouseDragged(); - p.mouseDragging = true - } - }); - attachEventHandler(curElement, "mouseout", function(e) { - if (typeof p.mouseOut === "function") p.mouseOut() - }); - attachEventHandler(curElement, "mouseover", function(e) { - updateMousePosition(curElement, e); - if (typeof p.mouseOver === "function") p.mouseOver() - }); - attachEventHandler(curElement, "mousedown", function(e) { - p.__mousePressed = true; - p.mouseDragging = false; - switch (e.which) { - case 1: - p.mouseButton = 37; - break; - case 2: - p.mouseButton = 3; - break; - case 3: - p.mouseButton = 39; - break - } - if (typeof p.mousePressed === "function") p.mousePressed() - }); - attachEventHandler(curElement, "mouseup", function(e) { - p.__mousePressed = false; - if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); - if (typeof p.mouseReleased === "function") p.mouseReleased() - }); - var mouseWheelHandler = function(e) { - var delta = 0; - if (e.wheelDelta) { - delta = e.wheelDelta / 120; - if (window.opera) delta = -delta - } else if (e.detail) delta = -e.detail / 3; - p.mouseScroll = delta; - if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled() - }; - attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); - attachEventHandler(document, "mousewheel", mouseWheelHandler); - if (typeof curElement === "string") curElement = document.getElementById(curElement); - if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); - - function getKeyCode(e) { - var code = e.which || e.keyCode; - switch (code) { - case 13: - return 10; - case 91: - case 93: - case 224: - return 157; - case 57392: - return 17; - case 46: - return 127; - case 45: - return 155 - } - return code - } - function getKeyChar(e) { - var c = e.which || e.keyCode; - var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; - switch (c) { - case 13: - c = anyShiftPressed ? 13 : 10; - break; - case 8: - c = anyShiftPressed ? 127 : 8; - break - } - return new Char(c) - } - function suppressKeyEvent(e) { - if (typeof e.preventDefault === "function") e.preventDefault(); - else if (typeof e.stopPropagation === "function") e.stopPropagation(); - return false - } - function updateKeyPressed() { - var ch; - for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { - p.__keyPressed = true; - return - } - p.__keyPressed = false - } - function resetKeyPressed() { - p.__keyPressed = false; - pressedKeysMap = []; - lastPressedKeyCode = null - } - function simulateKeyTyped(code, c) { - pressedKeysMap[code] = c; - lastPressedKeyCode = null; - p.key = c; - p.keyCode = code; - p.keyPressed(); - p.keyCode = 0; - p.keyTyped(); - updateKeyPressed() - } - function handleKeydown(e) { - var code = getKeyCode(e); - if (code === 127) { - simulateKeyTyped(code, new Char(127)); - return - } - if (codedKeys.indexOf(code) < 0) { - lastPressedKeyCode = code; - return - } - var c = new Char(65535); - p.key = c; - p.keyCode = code; - pressedKeysMap[code] = c; - p.keyPressed(); - lastPressedKeyCode = null; - updateKeyPressed(); - return suppressKeyEvent(e) - } - function handleKeypress(e) { - if (lastPressedKeyCode === null) return; - var code = lastPressedKeyCode, - c = getKeyChar(e); - simulateKeyTyped(code, c); - return suppressKeyEvent(e) - } - function handleKeyup(e) { - var code = getKeyCode(e), - c = pressedKeysMap[code]; - if (c === undef) return; - p.key = c; - p.keyCode = code; - p.keyReleased(); - delete pressedKeysMap[code]; - updateKeyPressed() - } - if (!pgraphicsMode) { - if (aCode instanceof Processing.Sketch) curSketch = aCode; - else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); - else if (!aCode) curSketch = new Processing.Sketch(function() {}); - else curSketch = Processing.compile(aCode); - p.externals.sketch = curSketch; - wireDimensionalFunctions(); - curElement.onfocus = function() { - p.focused = true - }; - curElement.onblur = function() { - p.focused = false; - if (!curSketch.options.globalKeyEvents) resetKeyPressed() - }; - if (curSketch.options.pauseOnBlur) { - attachEventHandler(window, "focus", function() { - if (doLoop) p.loop() - }); - attachEventHandler(window, "blur", function() { - if (doLoop && loopStarted) { - p.noLoop(); - doLoop = true - } - resetKeyPressed() - }) - } - var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; - attachEventHandler(keyTrigger, "keydown", handleKeydown); - attachEventHandler(keyTrigger, "keypress", handleKeypress); - attachEventHandler(keyTrigger, "keyup", handleKeyup); - for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p); - else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this); - var retryInterval = 100; - var executeSketch = function(processing) { - if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { - if (window.opera) { - var link, element, operaCache = curSketch.imageCache.operaCache; - for (link in operaCache) if (operaCache.hasOwnProperty(link)) { - element = operaCache[link]; - if (element !== null) document.body.removeChild(element); - delete operaCache[link] - } - } - curSketch.attach(processing, defaultScope); - curSketch.onLoad(processing); - if (processing.setup) { - processing.setup(); - processing.resetMatrix(); - curSketch.onSetup() - } - resetContext(); - if (processing.draw) if (!doLoop) processing.redraw(); - else processing.loop() - } else window.setTimeout(function() { - executeSketch(processing) - }, - retryInterval) - }; - addInstance(this); - executeSketch(p) - } else { - curSketch = new Processing.Sketch; - wireDimensionalFunctions(); - p.size = function(w, h, render) { - if (render && render === 2) wireDimensionalFunctions("3D"); - else wireDimensionalFunctions("2D"); - p.size(w, h, render) - } - } - }; - Processing.debug = debug; - Processing.prototype = defaultScope; - - function getGlobalMembers() { - var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append", "applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", - "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", - "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", "loadImage", "loadPixels", "loadShape", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", - "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", - "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation", "save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", - "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData", "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", - "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith"]; - var members = {}; - var i, l; - for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null; - for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) { - var exportedNames = Processing.lib[lib].exports; - for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null - } - return members - } - function parseProcessing(code) { - var globalMembers = getGlobalMembers(); - - function splitToAtoms(code) { - var atoms = []; - var items = code.split(/([\{\[\(\)\]\}])/); - var result = items[0]; - var stack = []; - for (var i = 1; i < items.length; i += 2) { - var item = items[i]; - if (item === "[" || item === "{" || item === "(") { - stack.push(result); - result = item - } else if (item === "]" || item === "}" || item === ")") { - var kind = item === "}" ? "A" : item === ")" ? "B" : "C"; - var index = atoms.length; - atoms.push(result + item); - result = stack.pop() + '"' + kind + (index + 1) + '"' - } - result += items[i + 1] - } - atoms.unshift(result); - return atoms - } - function injectStrings(code, strings) { - return code.replace(/'(\d+)'/g, function(all, index) { - var val = strings[index]; - if (val.charAt(0) === "/") return val; - return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val - }) - } - function trimSpaces(string) { - var m1 = /^\s*/.exec(string), - result; - if (m1[0].length === string.length) result = { - left: m1[0], - middle: "", - right: "" - }; - else { - var m2 = /\s*$/.exec(string); - result = { - left: m1[0], - middle: string.substring(m1[0].length, m2.index), - right: m2[0] - } - } - result.untrim = function(t) { - return this.left + t + this.right - }; - return result - } - function trim(string) { - return string.replace(/^\s+/, "").replace(/\s+$/, "") - } - function appendToLookupTable(table, array) { - for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null; - return table - } - function isLookupTableEmpty(table) { - for (var i in table) if (table.hasOwnProperty(i)) return false; - return true - } - function getAtomIndex(templ) { - return templ.substring(2, templ.length - 1) - } - var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n"); - var strings = []; - var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) { - var index; - if (quoted || aposed) { - index = strings.length; - strings.push(all); - return "'" + index + "'" - } - if (regexCtx) { - index = strings.length; - strings.push(regex); - return prefix + "'" + index + "'" - } - return comment !== "" ? " " : "\n" - }); - var genericsWereRemoved; - var codeWoGenerics = codeWoStrings; - var replaceFunc = function(all, before, types, after) { - if ( !! before || !!after) return all; - genericsWereRemoved = true; - return "" - }; - do { - genericsWereRemoved = false; - codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) - } while (genericsWereRemoved); - var atoms = splitToAtoms(codeWoGenerics); - var replaceContext; - var declaredClasses = {}, - currentClassId, classIdSeed = 0; - - function addAtom(text, type) { - var lastIndex = atoms.length; - atoms.push(text); - return '"' + type + lastIndex + '"' - } - function generateClassId() { - return "class" + ++classIdSeed - } - function appendClass(class_, classId, scopeId) { - class_.classId = classId; - class_.scopeId = scopeId; - declaredClasses[classId] = class_ - } - var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression; - var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g; - var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g; - var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/; - var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g; - var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/; - var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g; - - function extractClassesAndMethods(code) { - var s = code; - s = s.replace(classesRegex, function(all) { - return addAtom(all, "E") - }); - s = s.replace(methodsRegex, function(all) { - return addAtom(all, "D") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - return s - } - function extractConstructors(code, className) { - var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) { - if (name !== className) return all; - return addAtom(all, "G") - }); - return result - } - function AstParam(name) { - this.name = name - } - AstParam.prototype.toString = function() { - return this.name - }; - - function AstParams(params) { - this.params = params - } - AstParams.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name); - return names - }; - AstParams.prototype.toString = function() { - if (this.params.length === 0) return "()"; - var result = "("; - for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", "; - return result.substring(0, result.length - 2) + ")" - }; - - function transformParams(params) { - var paramsWoPars = trim(params.substring(1, params.length - 1)); - var result = []; - if (paramsWoPars !== "") { - var paramList = paramsWoPars.split(","); - for (var i = 0; i < paramList.length; ++i) { - var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]); - result.push(new AstParam(param[1])) - } - } - return new AstParams(result) - } - function preExpressionTransform(expr) { - var s = expr; - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) { - return init - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) { - return addAtom(all, "F") - }); - s = s.replace(functionsRegex, function(all) { - return addAtom(all, "H") - }); - s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) { - var args = index.replace(/"C(\d+)"/g, function(all, j) { - return atoms[j] - }).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", "); - var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}"; - var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")"; - return "$p.createJavaArray" + addAtom(createArrayArgs, "B") - }); - s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1"); - s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) { - return "0xFF" + digits - }); - s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) { - var atom = atoms[index]; - if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all; - if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; - var indexParts = atom.split(/"C(\d+)"/g); - if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all; - return "" + next - }); - s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) { - var trimmed = trimSpaces(arg); - return trimmed.untrim("__int_cast(" + trimmed.middle + ")") - }); - s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1"); - s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) { - if (numberWo0 === intPart) return all; - return intPart === "" ? "0" + numberWo0 : numberWo0 - }); - s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1"); - s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2"); - s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1"); - s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { - return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' - }); - s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) { - if (index) { - var atom = atoms[atomIndex]; - if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B"); - return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") - } - if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); - if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); - return "pixels.toArray" + addAtom("()", "B") - }); - var repeatJavaReplacement; - - function replacePrototypeMethods(all, subject, method, atomIndex) { - var atom = atoms[atomIndex]; - repeatJavaReplacement = true; - var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); - return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt)\s*"B(\d+)"/g, replacePrototypeMethods) - } while (repeatJavaReplacement); - - function replaceInstanceof(all, subject, type) { - repeatJavaReplacement = true; - return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") - } - do { - repeatJavaReplacement = false; - s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) - } while (repeatJavaReplacement); - s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1"); - return s - } - function AstInlineClass(baseInterfaceName, body) { - this.baseInterfaceName = baseInterfaceName; - this.body = body; - body.owner = this - } - AstInlineClass.prototype.toString = function() { - return "new (" + this.body + ")" - }; - - function transformInlineClass(class_) { - var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var uniqueClassName = m[1] + "$" + newClassId; - var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1])); - appendClass(inlineClass, newClassId, oldClassId); - currentClassId = oldClassId; - return inlineClass - } - function AstFunction(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstFunction.prototype.toString = function() { - var oldContext = replaceContext; - var names = appendToLookupTable({ - "this": null - }, - this.params.getNames()); - replaceContext = function(subject) { - return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function"; - if (this.name) result += " " + this.name; - result += this.params + " " + this.body; - replaceContext = oldContext; - return result - }; - - function transformFunction(class_) { - var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_); - return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]])) - } - function AstInlineObject(members) { - this.members = members - } - AstInlineObject.prototype.toString = function() { - var oldContext = replaceContext; - replaceContext = function(subject) { - return subject.name === "this" ? "this" : oldContext(subject) - }; - var result = ""; - for (var i = 0, l = this.members.length; i < l; ++i) { - if (this.members[i].label) result += this.members[i].label + ": "; - result += this.members[i].value.toString() + ", " - } - replaceContext = oldContext; - return result.substring(0, result.length - 2) - }; - - function transformInlineObject(obj) { - var members = obj.split(","); - for (var i = 0; i < members.length; ++i) { - var label = members[i].indexOf(":"); - if (label < 0) members[i] = { - value: transformExpression(members[i]) - }; - else members[i] = { - label: trim(members[i].substring(0, label)), - value: transformExpression(trim(members[i].substring(label + 1))) - } - } - return new AstInlineObject(members) - } - function expandExpression(expr) { - if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1); - if (expr.charAt(0) === "{") { - if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; - return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" - } - var trimmed = trimSpaces(expr); - var result = preExpressionTransform(trimmed.middle); - result = result.replace(/"[ABC](\d+)"/g, function(all, index) { - return expandExpression(atoms[index]) - }); - return trimmed.untrim(result) - } - function replaceContextInVars(expr) { - return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { - if (memberAccessSign) return all; - var subject = { - name: identifier, - member: subMember, - callSign: !!callSign - }; - return replaceContext(subject) + (suffix === undef ? "" : suffix) - }) - } - function AstExpression(expr, transforms) { - this.expr = expr; - this.transforms = transforms - } - AstExpression.prototype.toString = function() { - var transforms = this.transforms; - var expr = replaceContextInVars(this.expr); - return expr.replace(/"!(\d+)"/g, function(all, index) { - return transforms[index].toString() - }) - }; - transformExpression = function(expr) { - var transforms = []; - var s = expandExpression(expr); - s = s.replace(/"H(\d+)"/g, function(all, index) { - transforms.push(transformFunction(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"F(\d+)"/g, function(all, index) { - transforms.push(transformInlineClass(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - s = s.replace(/"I(\d+)"/g, function(all, index) { - transforms.push(transformInlineObject(atoms[index])); - return '"!' + (transforms.length - 1) + '"' - }); - return new AstExpression(s, transforms) - }; - - function AstVarDefinition(name, value, isDefault) { - this.name = name; - this.value = value; - this.isDefault = isDefault - } - AstVarDefinition.prototype.toString = function() { - return this.name + " = " + this.value - }; - - function transformVarDefinition(def, defaultTypeValue) { - var eqIndex = def.indexOf("="); - var name, value, isDefault; - if (eqIndex < 0) { - name = def; - value = defaultTypeValue; - isDefault = true - } else { - name = def.substring(0, eqIndex); - value = transformExpression(def.substring(eqIndex + 1)); - isDefault = false - } - return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault) - } - function getDefaultValueForType(type) { - if (type === "int" || type === "float") return "0"; - if (type === "boolean") return "false"; - if (type === "color") return "0x00000000"; - return "null" - } - function AstVar(definitions, varType) { - this.definitions = definitions; - this.varType = varType - } - AstVar.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstVar.prototype.toString = function() { - return "var " + this.definitions.join(",") - }; - - function AstStatement(expression) { - this.expression = expression - } - AstStatement.prototype.toString = function() { - return this.expression.toString() - }; - - function transformStatement(statement) { - if (fieldTest.test(statement)) { - var attrAndType = attrAndTypeRegex.exec(statement); - var definitions = statement.substring(attrAndType[0].length).split(","); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstVar(definitions, attrAndType[2]) - } - return new AstStatement(transformExpression(statement)) - } - function AstForExpression(initStatement, condition, step) { - this.initStatement = initStatement; - this.condition = condition; - this.step = step - } - AstForExpression.prototype.toString = function() { - return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")" - }; - - function AstForInExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForInExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("=")); - return "(" + init + " in " + this.container + ")" - }; - - function AstForEachExpression(initStatement, container) { - this.initStatement = initStatement; - this.container = container - } - AstForEachExpression.iteratorId = 0; - AstForEachExpression.prototype.toString = function() { - var init = this.initStatement.toString(); - var iterator = "$it" + AstForEachExpression.iteratorId++; - var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; - var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; - var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; - return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" - }; - - function transformForExpression(expr) { - var content; - if (/\bin\b/.test(expr)) { - content = expr.substring(1, expr.length - 1).split(/\bin\b/g); - return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { - content = expr.substring(1, expr.length - 1).split(":"); - return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) - } - content = expr.substring(1, expr.length - 1).split(";"); - return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) - } - function sortByWeight(array) { - array.sort(function(a, b) { - return b.weight - a.weight - }) - } - function AstInnerInterface(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerInterface.prototype.toString = function() { - return "" + this.body - }; - - function AstInnerClass(name, body, isStatic) { - this.name = name; - this.body = body; - this.isStatic = isStatic; - body.owner = this - } - AstInnerClass.prototype.toString = function() { - return "" + this.body - }; - - function transformInnerClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = atoms[getAtomIndex(m[6])], - innerClass; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); - else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); - appendClass(innerClass, newClassId, oldClassId); - currentClassId = oldClassId; - return innerClass - } - function AstClassMethod(name, params, body, isStatic) { - this.name = name; - this.params = params; - this.body = body; - this.isStatic = isStatic - } - AstClassMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.methodId + this.params + " " + this.body + "\n"; - replaceContext = oldContext; - return result - }; - - function transformClassMethod(method) { - var m = methodsRegex.exec(method); - methodsRegex.lastIndex = 0; - var isStatic = m[1].indexOf("static") >= 0; - var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; - return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) - } - function AstClassField(definitions, fieldType, isStatic) { - this.definitions = definitions; - this.fieldType = fieldType; - this.isStatic = isStatic - } - AstClassField.prototype.getNames = function() { - var names = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name); - return names - }; - AstClassField.prototype.toString = function() { - var thisPrefix = replaceContext({ - name: "[this]" - }); - if (this.isStatic) { - var className = this.owner.name; - var staticDeclarations = []; - for (var i = 0, l = this.definitions.length; i < l; ++i) { - var definition = this.definitions[i]; - var name = definition.name, - staticName = className + "." + name; - var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n"; - staticDeclarations.push(declaration) - } - return staticDeclarations.join("") - } - return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".") - }; - - function transformClassField(statement) { - var attrAndType = attrAndTypeRegex.exec(statement); - var isStatic = attrAndType[1].indexOf("static") >= 0; - var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g); - var defaultTypeValue = getDefaultValueForType(attrAndType[2]); - for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue); - return new AstClassField(definitions, attrAndType[2], isStatic) - } - function AstConstructor(params, body) { - this.params = params; - this.body = body - } - AstConstructor.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var prefix = "function $constr_" + this.params.params.length + this.params.toString(); - var body = this.body.toString(); - if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1); - replaceContext = oldContext; - return prefix + body + "\n" - }; - - function transformConstructor(cstr) { - var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr); - var params = transformParams(atoms[m[1]]); - return new AstConstructor(params, transformStatementsBlock(atoms[m[2]])) - } - function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { - var i, l; - this.name = name; - this.interfacesNames = interfacesNames; - this.methodsNames = methodsNames; - this.fields = fields; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methodsNames.length; i < l; ++i) { - var methodName = this.methodsNames[i]; - classMethods[methodName] = true - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstInterfaceBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var className = this.name; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = replaceContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - metadata += className + ".$isInterface = true;\n"; - metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" - } - return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformInterfaceBody = function(body, name, baseInterfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methodsNames = [], - classes = []; - declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { - if (type === "D") methodsNames.push(index); - else if (type === "E") classes.push(index); - return "" - }); - var fields = declarations.split(/;(?:\s*;)*/g); - var baseInterfaceNames; - var i, l; - if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0, l = methodsNames.length; i < l; ++i) { - var method = transformClassMethod(atoms[methodsNames[i]]); - methodsNames[i] = method.name - } - for (i = 0, l = fields.length - 1; i < l; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { - tail: tail - }) - }; - - function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { - var i, l; - this.name = name; - this.baseClassName = baseClassName; - this.interfacesNames = interfacesNames; - this.functions = functions; - this.methods = methods; - this.fields = fields; - this.cstrs = cstrs; - this.innerClasses = innerClasses; - this.misc = misc; - for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this - } - AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) { - if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); - var i, j, l, m; - for (i = 0, l = this.fields.length; i < l; ++i) { - var fieldNames = this.fields[i].getNames(); - for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] - } - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - classMethods[method.name] = method - } - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - classInners[innerClass.name] = innerClass - } - }; - AstClassBody.prototype.toString = function() { - function getScopeLevel(p) { - var i = 0; - while (p) { - ++i; - p = p.scope - } - return i - } - var scopeLevel = getScopeLevel(this.owner); - var selfId = "$this_" + scopeLevel; - var className = this.name; - var result = "var " + selfId + " = this;\n"; - var staticDefinitions = ""; - var metadata = ""; - var thisClassFields = {}, - thisClassMethods = {}, - thisClassInners = {}; - this.getMembers(thisClassFields, thisClassMethods, thisClassInners); - var oldContext = replaceContext; - replaceContext = function(subject) { - var name = subject.name; - if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; - if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; - if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; - if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; - return oldContext(subject) - }; - var resolvedBaseClassName; - if (this.baseClassName) { - resolvedBaseClassName = oldContext({ - name: this.baseClassName - }); - result += "var $super = { $upcast: " + selfId + " };\n"; - result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; - metadata += className + ".$base = " + resolvedBaseClassName + ";\n" - } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; - if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; - var i, l, j, m; - if (this.owner.interfaces) { - var resolvedInterfaces = [], - resolvedInterface; - for (i = 0, l = this.interfacesNames.length; i < l; ++i) { - if (!this.owner.interfaces[i]) continue; - resolvedInterface = oldContext({ - name: this.interfacesNames[i] - }); - resolvedInterfaces.push(resolvedInterface); - staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" - } - metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" - } - if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; - sortByWeight(this.innerClasses); - for (i = 0, l = this.innerClasses.length; i < l; ++i) { - var innerClass = this.innerClasses[i]; - if (innerClass.isStatic) { - staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; - result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" - } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" - } - for (i = 0, l = this.fields.length; i < l; ++i) { - var field = this.fields[i]; - if (field.isStatic) { - staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; - for (j = 0, m = field.definitions.length; j < m; ++j) { - var fieldName = field.definitions[j].name, - staticName = className + "." + fieldName; - result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" - } - } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" - } - var methodOverloads = {}; - for (i = 0, l = this.methods.length; i < l; ++i) { - var method = this.methods[i]; - var overload = methodOverloads[method.name]; - var methodId = method.name + "$" + method.params.params.length; - if (overload) { - ++overload; - methodId += "_" + overload - } else overload = 1; - method.methodId = methodId; - methodOverloads[method.name] = overload; - if (method.isStatic) { - staticDefinitions += method; - staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ");\n"; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } else { - result += method; - result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ");\n" - } - } - result += trim(this.misc.tail); - if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; - result += "function $constr() {\n"; - var cstrsIfs = []; - for (i = 0, l = this.cstrs.length; i < l; ++i) { - var paramsLength = this.cstrs[i].params.params.length; - cstrsIfs.push("if(arguments.length === " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") - } - if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; - result += "$superCstr();\n}\n"; - result += "$constr.apply(null, arguments);\n"; - replaceContext = oldContext; - return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" - }; - transformClassBody = function(body, name, baseName, interfaces) { - var declarations = body.substring(1, body.length - 1); - declarations = extractClassesAndMethods(declarations); - declarations = extractConstructors(declarations, name); - var methods = [], - classes = [], - cstrs = [], - functions = []; - declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) { - if (type === "D") methods.push(index); - else if (type === "E") classes.push(index); - else if (type === "H") functions.push(index); - else cstrs.push(index); - return "" - }); - var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); - var baseClassName, interfacesNames; - var i; - if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); - if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); - for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]); - for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]); - for (i = 0; i < fields.length - 1; ++i) { - var field = trimSpaces(fields[i]); - fields[i] = transformClassField(field.middle) - } - var tail = fields.pop(); - for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]); - for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); - return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, { - tail: tail - }) - }; - - function AstInterface(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstInterface.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function AstClass(name, body) { - this.name = name; - this.body = body; - body.owner = this - } - AstClass.prototype.toString = function() { - return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" - }; - - function transformGlobalClass(class_) { - var m = classesRegex.exec(class_); - classesRegex.lastIndex = 0; - var body = atoms[getAtomIndex(m[6])]; - var oldClassId = currentClassId, - newClassId = generateClassId(); - currentClassId = newClassId; - var globalClass; - if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); - else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5])); - appendClass(globalClass, newClassId, oldClassId); - currentClassId = oldClassId; - return globalClass - } - function AstMethod(name, params, body) { - this.name = name; - this.params = params; - this.body = body - } - AstMethod.prototype.toString = function() { - var paramNames = appendToLookupTable({}, - this.params.getNames()); - var oldContext = replaceContext; - replaceContext = function(subject) { - return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "function " + this.name + this.params + " " + this.body + "\n" + "$p." + this.name + " = " + this.name + ";"; - replaceContext = oldContext; - return result - }; - - function transformGlobalMethod(method) { - var m = methodsRegex.exec(method); - var result = methodsRegex.lastIndex = 0; - return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])])) - } - function preStatementsTransform(statements) { - var s = statements; - s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1"); - return s - } - function AstForStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstForStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstCatchStatement(argument, misc) { - this.argument = argument; - this.misc = misc - } - AstCatchStatement.prototype.toString = function() { - return this.misc.prefix + this.argument.toString() - }; - - function AstPrefixStatement(name, argument, misc) { - this.name = name; - this.argument = argument; - this.misc = misc - } - AstPrefixStatement.prototype.toString = function() { - var result = this.misc.prefix; - if (this.argument !== undef) result += this.argument.toString(); - return result - }; - - function AstSwitchCase(expr) { - this.expr = expr - } - AstSwitchCase.prototype.toString = function() { - return "case " + this.expr + ":" - }; - - function AstLabel(label) { - this.label = label - } - AstLabel.prototype.toString = function() { - return this.label - }; - transformStatements = function(statements, transformMethod, transformClass) { - var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g); - var res = []; - statements = preStatementsTransform(statements); - var lastIndex = 0, - m, space; - while ((m = nextStatement.exec(statements)) !== null) { - if (m[1] !== undef) { - var i = statements.lastIndexOf('"B', nextStatement.lastIndex); - var statementsPrefix = statements.substring(lastIndex, i); - if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), { - prefix: statementsPrefix - })); - else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), { - prefix: statementsPrefix - })); - else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), { - prefix: statementsPrefix - })) - } else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, { - prefix: statements.substring(lastIndex, nextStatement.lastIndex) - })); - else if (m[4] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length); - if (trim(space).length !== 0) continue; - res.push(space); - var kind = m[4].charAt(1), - atomIndex = m[5]; - if (kind === "D") res.push(transformMethod(atoms[atomIndex])); - else if (kind === "E") res.push(transformClass(atoms[atomIndex])); - else if (kind === "H") res.push(transformFunction(atoms[atomIndex])); - else res.push(transformStatementsBlock(atoms[atomIndex])) - } else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); - else if (m[8] !== undef) { - space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length); - if (trim(space).length !== 0) continue; - res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex))) - } else { - var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1)); - res.push(statement.left); - res.push(transformStatement(statement.middle)); - res.push(statement.right + ";") - } - lastIndex = nextStatement.lastIndex - } - var statementsTail = trimSpaces(statements.substring(lastIndex)); - res.push(statementsTail.left); - if (statementsTail.middle !== "") { - res.push(transformStatement(statementsTail.middle)); - res.push(";" + statementsTail.right) - } - return res - }; - - function getLocalNames(statements) { - var localNames = []; - for (var i = 0, l = statements.length; i < l; ++i) { - var statement = statements[i]; - if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames()); - else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames()); - else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name) - } - return appendToLookupTable({}, - localNames) - } - function AstStatementsBlock(statements) { - this.statements = statements - } - AstStatementsBlock.prototype.toString = function() { - var localNames = getLocalNames(this.statements); - var oldContext = replaceContext; - if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) { - return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject) - }; - var result = "{\n" + this.statements.join("") + "\n}"; - replaceContext = oldContext; - return result - }; - transformStatementsBlock = function(block) { - var content = trimSpaces(block.substring(1, block.length - 1)); - return new AstStatementsBlock(transformStatements(content.middle)) - }; - - function AstRoot(statements) { - this.statements = statements - } - AstRoot.prototype.toString = function() { - var classes = [], - otherStatements = [], - statement; - for (var i = 0, len = this.statements.length; i < len; ++i) { - statement = this.statements[i]; - if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); - else otherStatements.push(statement) - } - sortByWeight(classes); - var localNames = getLocalNames(this.statements); - replaceContext = function(subject) { - var name = subject.name; - if (localNames.hasOwnProperty(name)) return name; - if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name; - return name - }; - var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})"; - replaceContext = null; - return result - }; - transformMain = function() { - var statements = extractClassesAndMethods(atoms[0]); - statements = statements.replace(/\bimport\s+[^;]+;/g, ""); - return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass)) - }; - - function generateMetadata(ast) { - var globalScope = {}; - var id, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var scopeId = class_.scopeId, - name = class_.name; - if (scopeId) { - var scope = declaredClasses[scopeId]; - class_.scope = scope; - if (scope.inScope === undef) scope.inScope = {}; - scope.inScope[name] = class_ - } else globalScope[name] = class_ - } - function findInScopes(class_, name) { - var parts = name.split("."); - var currentScope = class_.scope, - found; - while (currentScope) { - if (currentScope.hasOwnProperty(parts[0])) { - found = currentScope[parts[0]]; - break - } - currentScope = currentScope.scope - } - if (found === undef) found = globalScope[parts[0]]; - for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]]; - return found - } - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - var baseClassName = class_.body.baseClassName; - if (baseClassName) { - var parent = findInScopes(class_, baseClassName); - if (parent) { - class_.base = parent; - if (!parent.derived) parent.derived = []; - parent.derived.push(class_) - } - } - var interfacesNames = class_.body.interfacesNames, - interfaces = [], - i, l; - if (interfacesNames && interfacesNames.length > 0) { - for (i = 0, l = interfacesNames.length; i < l; ++i) { - var interface_ = findInScopes(class_, interfacesNames[i]); - interfaces.push(interface_); - if (!interface_) continue; - if (!interface_.derived) interface_.derived = []; - interface_.derived.push(class_) - } - if (interfaces.length > 0) class_.interfaces = interfaces - } - } - } - function setWeight(ast) { - var queue = [], - tocheck = {}; - var id, scopeId, class_; - for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { - class_ = declaredClasses[id]; - if (!class_.inScope && !class_.derived) { - queue.push(id); - class_.weight = 0 - } else { - var dependsOn = []; - if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); - if (class_.derived) dependsOn = dependsOn.concat(class_.derived); - tocheck[id] = dependsOn - } - } - function removeDependentAndCheck(targetId, from) { - var dependsOn = tocheck[targetId]; - if (!dependsOn) return false; - var i = dependsOn.indexOf(from); - if (i < 0) return false; - dependsOn.splice(i, 1); - if (dependsOn.length > 0) return false; - delete tocheck[targetId]; - return true - } - while (queue.length > 0) { - id = queue.shift(); - class_ = declaredClasses[id]; - if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { - queue.push(class_.scopeId); - declaredClasses[class_.scopeId].weight = class_.weight + 1 - } - if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { - queue.push(class_.base.classId); - class_.base.weight = class_.weight + 1 - } - if (class_.interfaces) { - var i, l; - for (i = 0, l = class_.interfaces.length; i < l; ++i) { - if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; - queue.push(class_.interfaces[i].classId); - class_.interfaces[i].weight = class_.weight + 1 - } - } - } - } - var transformed = transformMain(); - generateMetadata(transformed); - setWeight(transformed); - var redendered = transformed.toString(); - redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); - return injectStrings(redendered, strings) - } - function preprocessCode(aCode, sketch) { - var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode); - if (dm && dm.length === 2) { - var jsonItems = [], - directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() { - return function(all, item) { - jsonItems.push(item); - return "{" + (jsonItems.length - 1) + "}" - } - }()).replace("\n", "").replace("\r", "").split(";"); - var clean = function(s) { - return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "") - }; - for (var i = 0, dl = directives.length; i < dl; i++) { - var pair = directives[i].split("="); - if (pair && pair.length === 2) { - var key = clean(pair[0]), - value = clean(pair[1]), - list = []; - if (key === "preload") { - list = value.split(","); - for (var j = 0, jl = list.length; j < jl; j++) { - var imageName = clean(list[j]); - sketch.imageCache.add(imageName) - } - } else if (key === "font") { - list = value.split(","); - for (var x = 0, xl = list.length; x < xl; x++) { - var fontName = clean(list[x]), - index = /^\{(\d*?)\}$/.exec(fontName); - PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) - } - } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; - else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; - else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; - else sketch.options[key] = value - } - } - } - return aCode - } - Processing.compile = function(pdeCode) { - var sketch = new Processing.Sketch; - var code = preprocessCode(pdeCode, sketch); - var compiledPde = parseProcessing(code); - sketch.sourceCode = compiledPde; - return sketch - }; - var tinylogLite = function() { - var tinylogLite = {}, - undef = "undefined", - func = "function", - False = !1, - True = !0, - logLimit = 512, - log = "log"; - if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log]; - else if (typeof document !== undef && !document.fake)(function() { - var doc = document, - $div = "div", - $style = "style", - $title = "title", - containerStyles = { - zIndex: 1E4, - position: "fixed", - bottom: "0px", - width: "100%", - height: "15%", - fontFamily: "sans-serif", - color: "#ccc", - backgroundColor: "black" - }, - outputStyles = { - position: "relative", - fontFamily: "monospace", - overflow: "auto", - height: "100%", - paddingTop: "5px" - }, - resizerStyles = { - height: "5px", - marginTop: "-5px", - cursor: "n-resize", - backgroundColor: "darkgrey" - }, - closeButtonStyles = { - position: "absolute", - top: "5px", - right: "20px", - color: "#111", - MozBorderRadius: "4px", - webkitBorderRadius: "4px", - borderRadius: "4px", - cursor: "pointer", - fontWeight: "normal", - textAlign: "center", - padding: "3px 5px", - backgroundColor: "#333", - fontSize: "12px" - }, - entryStyles = { - minHeight: "16px" - }, - entryTextStyles = { - fontSize: "12px", - margin: "0 8px 0 8px", - maxWidth: "100%", - whiteSpace: "pre-wrap", - overflow: "auto" - }, - view = doc.defaultView, - docElem = doc.documentElement, - docElemStyle = docElem[$style], - setStyles = function() { - var i = arguments.length, - elemStyle, styles, style; - while (i--) { - styles = arguments[i--]; - elemStyle = arguments[i][$style]; - for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style] - } - }, - observer = function(obj, event, handler) { - if (obj.addEventListener) obj.addEventListener(event, handler, False); - else if (obj.attachEvent) obj.attachEvent("on" + event, handler); - return [obj, event, handler] - }, - unobserve = function(obj, event, handler) { - if (obj.removeEventListener) obj.removeEventListener(event, handler, False); - else if (obj.detachEvent) obj.detachEvent("on" + event, handler) - }, - clearChildren = function(node) { - var children = node.childNodes, - child = children.length; - while (child--) node.removeChild(children.item(0)) - }, - append = function(to, elem) { - return to.appendChild(elem) - }, - createElement = function(localName) { - return doc.createElement(localName) - }, - createTextNode = function(text) { - return doc.createTextNode(text) - }, - createLog = tinylogLite[log] = function(message) { - var uninit, originalPadding = docElemStyle.paddingBottom, - container = createElement($div), - containerStyle = container[$style], - resizer = append(container, createElement($div)), - output = append(container, createElement($div)), - closeButton = append(container, createElement($div)), - resizingLog = False, - previousHeight = False, - previousScrollTop = False, - messages = 0, - updateSafetyMargin = function() { - docElemStyle.paddingBottom = container.clientHeight + "px" - }, - setContainerHeight = function(height) { - var viewHeight = view.innerHeight, - resizerHeight = resizer.clientHeight; - if (height < 0) height = 0; - else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight; - containerStyle.height = height / viewHeight * 100 + "%"; - updateSafetyMargin() - }, - observers = [observer(doc, "mousemove", function(evt) { - if (resizingLog) { - setContainerHeight(view.innerHeight - evt.clientY); - output.scrollTop = previousScrollTop - } - }), observer(doc, "mouseup", function() { - if (resizingLog) resizingLog = previousScrollTop = False - }), observer(resizer, "dblclick", function(evt) { - evt.preventDefault(); - if (previousHeight) { - setContainerHeight(previousHeight); - previousHeight = False - } else { - previousHeight = container.clientHeight; - containerStyle.height = "0px" - } - }), observer(resizer, "mousedown", function(evt) { - evt.preventDefault(); - resizingLog = True; - previousScrollTop = output.scrollTop - }), observer(resizer, "contextmenu", function() { - resizingLog = False - }), observer(closeButton, "click", function() { - uninit() - })]; - uninit = function() { - var i = observers.length; - while (i--) unobserve.apply(tinylogLite, observers[i]); - docElem.removeChild(container); - docElemStyle.paddingBottom = originalPadding; - clearChildren(output); - clearChildren(container); - tinylogLite[log] = createLog - }; - setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles); - closeButton[$title] = "Close Log"; - append(closeButton, createTextNode("\u2716")); - resizer[$title] = "Double-click to toggle log minimization"; - docElem.insertBefore(container, docElem.firstChild); - tinylogLite[log] = function(message) { - if (messages === logLimit) output.removeChild(output.firstChild); - else messages++; - var entry = append(output, createElement($div)), - entryText = append(entry, createElement($div)); - entry[$title] = (new Date).toLocaleTimeString(); - setStyles(entry, entryStyles, entryText, entryTextStyles); - append(entryText, createTextNode(message)); - output.scrollTop = output.scrollHeight - }; - tinylogLite[log](message); - updateSafetyMargin() - } - })(); - else if (typeof print === func) tinylogLite[log] = print; - return tinylogLite - }(); - Processing.logger = tinylogLite; - Processing.version = "1.3.6"; - Processing.lib = {}; - Processing.registerLibrary = function(name, desc) { - Processing.lib[name] = desc; - if (desc.hasOwnProperty("init")) desc.init(defaultScope) - }; - Processing.instances = processingInstances; - Processing.getInstanceById = function(name) { - return processingInstances[processingInstanceIds[name]] - }; - Processing.Sketch = function(attachFunction) { - this.attachFunction = attachFunction; - this.options = { - pauseOnBlur: false, - globalKeyEvents: false - }; - this.onLoad = nop; - this.onSetup = nop; - this.onPause = nop; - this.onLoop = nop; - this.onFrameStart = nop; - this.onFrameEnd = nop; - this.onExit = nop; - this.params = {}; - this.imageCache = { - pending: 0, - images: {}, - operaCache: {}, - add: function(href, img) { - if (this.images[href]) return; - if (!isDOMPresent) this.images[href] = null; - if (!img) { - img = new Image; - img.onload = function(owner) { - return function() { - owner.pending-- - } - }(this); - this.pending++; - img.src = href - } - this.images[href] = img; - if (window.opera) { - var div = document.createElement("div"); - div.appendChild(img); - div.style.position = "absolute"; - div.style.opacity = 0; - div.style.width = "1px"; - div.style.height = "1px"; - if (!this.operaCache[href]) { - document.body.appendChild(div); - this.operaCache[href] = div - } - } - } - }; - this.sourceCode = undefined; - this.attach = function(processing) { - if (typeof this.attachFunction === "function") this.attachFunction(processing); - else if (this.sourceCode) { - var func = (new Function("return (" + this.sourceCode + ");"))(); - func(processing); - this.attachFunction = func - } else throw "Unable to attach sketch to the processing instance"; - }; - this.toString = function() { - var i; - var code = "((function(Sketch) {\n"; - code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; - for (i in this.options) if (this.options.hasOwnProperty(i)) { - var value = this.options[i]; - code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" - } - for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; - code += "return sketch;\n})(Processing.Sketch))"; - return code - } - }; - var loadSketchFromSources = function(canvas, sources) { - var code = [], - errors = [], - sourcesCount = sources.length, - loaded = 0; - - function ajaxAsync(url, callback) { - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var error; - if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; - else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; - else error = "File is empty."; - callback(xhr.responseText, error) - } - }; - xhr.open("GET", url, true); - if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); - xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); - xhr.send(null) - } - function loadBlock(index, filename) { - function callback(block, error) { - code[index] = block; - ++loaded; - if (error) errors.push(filename + " ==> " + error); - if (loaded === sourcesCount) if (errors.length === 0) try { - return new Processing(canvas, code.join("\n")) - } catch(e) { - throw "Processing.js: Unable to execute pjs sketch: " + e; - } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); - } - if (filename.charAt(0) === "#") { - var scriptElement = document.getElementById(filename.substring(1)); - if (scriptElement) callback(scriptElement.text || scriptElement.textContent); - else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); - return - } - ajaxAsync(filename, callback) - } - for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) - }; - var init = function() { - document.removeEventListener("DOMContentLoaded", init, false); - var canvas = document.getElementsByTagName("canvas"), - filenames; - for (var i = 0, l = canvas.length; i < l; i++) { - var processingSources = canvas[i].getAttribute("data-processing-sources"); - if (processingSources === null) { - processingSources = canvas[i].getAttribute("data-src"); - if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc") - } - if (processingSources) { - filenames = processingSources.split(" "); - for (var j = 0; j < filenames.length;) if (filenames[j]) j++; - else filenames.splice(j, 1); - loadSketchFromSources(canvas[i], filenames) - } - } - var scripts = document.getElementsByTagName("script"); - var s, source, instance; - for (s = 0; s < scripts.length; s++) { - var script = scripts[s]; - if (!script.getAttribute) continue; - var type = script.getAttribute("type"); - if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { - var target = script.getAttribute("data-processing-target"); - canvas = undef; - if (target) canvas = document.getElementById(target); - else { - var nextSibling = script.nextSibling; - while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; - if (nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling - } - if (canvas) { - if (script.getAttribute("src")) { - filenames = script.getAttribute("src").split(/\s+/); - loadSketchFromSources(canvas, filenames); - continue - } - source = script.textContent || script.text; - instance = new Processing(canvas, source) - } - } - } - }; - Processing.loadSketchFromSources = loadSketchFromSources; - Processing.disableInit = function() { - if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) - }; - if (isDOMPresent) { - window["Processing"] = Processing; - document.addEventListener("DOMContentLoaded", init, false) - } else this.Processing = Processing -})(window, window.document, Math); - diff --git a/java/examples/Books/Nature of Code/chp9_ga/bruteforce/bruteforce.pde b/java/examples/Books/Nature of Code/chp9_ga/bruteforce/bruteforce.pde deleted file mode 100644 index c8a00ce51..000000000 --- a/java/examples/Books/Nature of Code/chp9_ga/bruteforce/bruteforce.pde +++ /dev/null @@ -1,16 +0,0 @@ - - -int now = millis(); - -int passedTime = millis() - now; -int count = 0; -while (passedTime < 1000) { - for (int i = 0; i < 33; i++) { - float r = random(27); - } - count++; - passedTime = millis() - now; -} -println(count); - - diff --git a/java/examples/Books/Nature of Code/introduction/Exc_I_10_NoiseLandscape/Exc_I_10_NoiseLandscape.pde b/java/examples/Books/Nature of Code/introduction/Exc_I_10_NoiseLandscape/Exc_I_10_NoiseLandscape.pde deleted file mode 100644 index ffef4e6ab..000000000 --- a/java/examples/Books/Nature of Code/introduction/Exc_I_10_NoiseLandscape/Exc_I_10_NoiseLandscape.pde +++ /dev/null @@ -1,32 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/teaching/nature - -// Landscape with height values according to Perlin noise - -Landscape land; -float theta = 0.0; - -void setup() { - - size(800,200,P3D); - - // Create a landscape object - land = new Landscape(20,800,400); -} - -void draw() { - - // Ok, visualize the landscape space - background(255); - pushMatrix(); - translate(width/2,height/2+20,-160); - rotateX(PI/3); - rotateZ(theta); - land.render(); - popMatrix(); - - land.calculate(); - - theta += 0.0025; -} diff --git a/java/examples/Books/Nature of Code/introduction/Exc_I_10_NoiseLandscape/Landscape.pde b/java/examples/Books/Nature of Code/introduction/Exc_I_10_NoiseLandscape/Landscape.pde deleted file mode 100644 index 7d1114ac5..000000000 --- a/java/examples/Books/Nature of Code/introduction/Exc_I_10_NoiseLandscape/Landscape.pde +++ /dev/null @@ -1,65 +0,0 @@ -// Daniel Shiffman -// -// "Landscape" example - -class Landscape { - - int scl; // size of each cell - int w, h; // width and height of thingie - int rows, cols; // number of rows and columns - float zoff = 0.0; // perlin noise argument - float[][] z; // using an array to store all the height values - - Landscape(int scl_, int w_, int h_) { - scl = scl_; - w = w_; - h = h_; - cols = w/scl; - rows = h/scl; - z = new float[cols][rows]; - } - - - // Calculate height values (based off a neural netork) - void calculate() { - float xoff = 0; - for (int i = 0; i < cols; i++) - { - float yoff = 0; - for (int j = 0; j < rows; j++) - { - z[i][j] = map(noise(xoff, yoff,zoff), 0, 1, -120, 120); - yoff += 0.1; - } - xoff += 0.1; - } - zoff+=0.01; - } - - // Render landscape as grid of quads - void render() { - // Every cell is an individual quad - // (could use quad_strip here, but produces funny results, investigate this) - for (int x = 0; x < z.length-1; x++) - { - for (int y = 0; y < z[x].length-1; y++) - { - // one quad at a time - // each quad's color is determined by the height value at each vertex - // (clean this part up) - stroke(0); - fill(100, 100); - pushMatrix(); - beginShape(QUADS); - translate(x*scl-w/2, y*scl-h/2, 0); - vertex(0, 0, z[x][y]); - vertex(scl, 0, z[x+1][y]); - vertex(scl, scl, z[x+1][y+1]); - vertex(0, scl, z[x][y+1]); - endShape(); - popMatrix(); - } - } - } -} - diff --git a/java/examples/Books/Nature of Code/introduction/Exc_I_9_Noise3D/Exc_I_9_Noise3D.pde b/java/examples/Books/Nature of Code/introduction/Exc_I_9_Noise3D/Exc_I_9_Noise3D.pde deleted file mode 100644 index 125f77be9..000000000 --- a/java/examples/Books/Nature of Code/introduction/Exc_I_9_Noise3D/Exc_I_9_Noise3D.pde +++ /dev/null @@ -1,47 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/ - -float increment = 0.01; -// The noise function's 3rd argument, a global variable that increments once per cycle -float zoff = 0.0; -// We will increment zoff differently than xoff and yoff -float zincrement = 0.02; - -void setup() { - size(200,200); -} - -void draw() { - background(0); - - // Optional: adjust noise detail here - // noiseDetail(8,0.65f); - - loadPixels(); - - float xoff = 0.0; // Start xoff at 0 - - // For every x,y coordinate in a 2D space, calculate a noise value and produce a brightness value - for (int x = 0; x < width; x++) { - xoff += increment; // Increment xoff - float yoff = 0.0; // For every xoff, start yoff at 0 - for (int y = 0; y < height; y++) { - yoff += increment; // Increment yoff - - // Calculate noise and scale by 255 - float bright = noise(xoff,yoff,zoff)*255; - - // Try using this line instead - //float bright = random(0,255); - - // Set each pixel onscreen to a grayscale value - pixels[x+y*width] = color(bright,bright,bright); - } - } - updatePixels(); - - zoff += zincrement; // Increment zoff - - -} diff --git a/java/examples/Books/Nature of Code/introduction/Figure_I_2_BellCurve/Figure_I_2_BellCurve.pde b/java/examples/Books/Nature of Code/introduction/Figure_I_2_BellCurve/Figure_I_2_BellCurve.pde deleted file mode 100644 index 72dc64e22..000000000 --- a/java/examples/Books/Nature of Code/introduction/Figure_I_2_BellCurve/Figure_I_2_BellCurve.pde +++ /dev/null @@ -1,38 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/ - -float[] heights; - -void setup() { - size(400, 200); - smooth(); -} - -void draw() { - background(255); - float e = 2.71828183; //"e", see http://mathforum.org/dr.math/faq/faq.e.html for more info - float[] heights = new float[width]; //use an array to store all the "y" values - float m = 0; //default mean of 0 - float sd = map(mouseX,0,width,0.4,2); //standard deviation based on mouseX - for (int i = 0; i < heights.length; i++) { - float xcoord = map(i,0,width,-3,3); - float sq2pi = sqrt(2*PI); //square root of 2 * PI - float xmsq = -1*(xcoord-m)*(xcoord-m); //-(x - mu)^2 - float sdsq = sd*sd; //variance (standard deviation squared) - heights[i] = (1 / (sd * sq2pi)) * (pow(e, (xmsq/sdsq))); //P(x) function - } - - // a little for loop that draws a line between each point on the graph - stroke(0); - strokeWeight(2); - noFill(); - beginShape(); - for (int i = 0; i < heights.length-1; i++) { - float x = i; - float y = map(heights[i], 0, 1, height-2, 2); - vertex(x, y); - } - endShape(); -} - diff --git a/java/examples/Books/Nature of Code/introduction/Figure_I_5_Noise1DGraph/Figure_I_5_Noise1DGraph.pde b/java/examples/Books/Nature of Code/introduction/Figure_I_5_Noise1DGraph/Figure_I_5_Noise1DGraph.pde deleted file mode 100644 index af4efc566..000000000 --- a/java/examples/Books/Nature of Code/introduction/Figure_I_5_Noise1DGraph/Figure_I_5_Noise1DGraph.pde +++ /dev/null @@ -1,27 +0,0 @@ -// The Nature of Code -// http://www.shiffman.net/ - -// TIME -float t = 0.0; - -void setup() { - size(400,200); - smooth(); -} - - -void draw() { - background(255); - float xoff = t; - noFill(); - stroke(0); - strokeWeight(2); - beginShape(); - for (int i = 0; i < width; i++) { - float y = noise(xoff)*height; - xoff += 0.01; - vertex(i,y); - } - endShape(); - t+= 0.01; -} diff --git a/java/examples/Books/Nature of Code/introduction/Figure_I_6_RandomGraph/Figure_I_6_RandomGraph.pde b/java/examples/Books/Nature of Code/introduction/Figure_I_6_RandomGraph/Figure_I_6_RandomGraph.pde deleted file mode 100644 index d1d4bd4fd..000000000 --- a/java/examples/Books/Nature of Code/introduction/Figure_I_6_RandomGraph/Figure_I_6_RandomGraph.pde +++ /dev/null @@ -1,22 +0,0 @@ -// The Nature of Code -// http://www.shiffman.net/ - -void setup() { - size(400,200); - smooth(); -} - - -void draw() { - background(255); - noFill(); - stroke(0); - strokeWeight(2); - beginShape(); - for (int i = 0; i < width; i++) { - float y = random(height); - vertex(i,y); - } - endShape(); - noLoop(); -} diff --git a/java/examples/Books/Nature of Code/introduction/Gaussian2/Gaussian2.pde b/java/examples/Books/Nature of Code/introduction/Gaussian2/Gaussian2.pde deleted file mode 100644 index 43992d4c6..000000000 --- a/java/examples/Books/Nature of Code/introduction/Gaussian2/Gaussian2.pde +++ /dev/null @@ -1,49 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/ - -Random generator; - -void setup() { - size(200,200); - background(0); - smooth(); - generator = new Random(); -} - -void draw() { - //create an alpha blended background - fill(0,1); - rect(0,0,width,height); - - //get 3 gaussian random numbers w/ mean of 0 and standard deviation of 1.0 - float r = (float) generator.nextGaussian(); - float g = (float) generator.nextGaussian(); - float b = (float) generator.nextGaussian(); - - //define standard deviation and mean - float sd = 100; float mean = 100; - //scale by standard deviation and mean - //also constrain to between (0,255) since we are dealing with color - r = constrain((r * sd) + mean,0,255); - - //repeat for g & b - sd = 20; mean = 200; - g = constrain((g * sd) + mean,0,255); - sd = 50; mean = 0; - b = constrain((b * sd) + mean,0,255); - - //get more gaussian numbers, this time for location - float xloc = (float) generator.nextGaussian(); - float yloc = (float) generator.nextGaussian(); - sd = width/10; - mean = width/2; - xloc = ( xloc * sd ) + mean; - yloc = ( yloc * sd ) + mean; - - //draw an ellipse with gaussian generated color and location - noStroke(); - fill(r,g,b); - ellipse(xloc,yloc,8,8); -} - diff --git a/java/examples/Books/Nature of Code/introduction/MonteCarloDistribution/MonteCarlo.pde b/java/examples/Books/Nature of Code/introduction/MonteCarloDistribution/MonteCarlo.pde deleted file mode 100644 index bc7cfab1a..000000000 --- a/java/examples/Books/Nature of Code/introduction/MonteCarloDistribution/MonteCarlo.pde +++ /dev/null @@ -1,66 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/ - -float[] vals; // Array to count how often a random # is picked -float[] norms; // Normalized version of above - -void setup() { - size(200, 200); - smooth(); - vals = new float[width]; - norms = new float[width]; -} - -void draw() { - background(100); - - // Pick a random number between 0 and 1 based on custom probability function - float n = montecarlo(); - - // What spot in the array did we pick - int index = int(n*width); - vals[index]++; - stroke(255); - - boolean normalization = false; - float maxy = 0.0; - - // Draw graph based on values in norms array - // If a value is greater than the height, set normalization to true - for (int x = 0; x < vals.length; x++) { - line(x, height, x, height-norms[x]); - if (vals[x] > height) normalization = true; - if (vals[x] > maxy) maxy = vals[x]; - } - - // If normalization is true then normalize to height - // Otherwise, just copy the info - for (int x = 0; x < vals.length; x++) { - if (normalization) norms[x] = (vals[x] / maxy) * (height); - else norms[x] = vals[x]; - } -} - -// An algorithm for picking a random number based on monte carlo method -// Here probability is determined by formula y = x -float montecarlo() { - // Have we found one yet - boolean foundone = false; - int hack = 0; // let's count just so we don't get stuck in an infinite loop by accident - while (!foundone && hack < 10000) { - // Pick two random numbers - float r1 = (float) random(1); - float r2 = (float) random(1); - float y = r1*r1; // y = x*x (change for different results) - // If r2 is valid, we'll use this one - if (r2 < y) { - foundone = true; - return r1; - } - hack++; - } - // Hack in case we run into a problem (need to improve this) - return 0; -} - diff --git a/java/examples/Books/Nature of Code/introduction/MultipleProbability/MultipleProbability.pde b/java/examples/Books/Nature of Code/introduction/MultipleProbability/MultipleProbability.pde deleted file mode 100644 index 74144ce1c..000000000 --- a/java/examples/Books/Nature of Code/introduction/MultipleProbability/MultipleProbability.pde +++ /dev/null @@ -1,39 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// ITP, Spring 2006 -// http://www.shiffman.net/ - -int x,y; - -void setup() { - size(200,200); - background(0); - smooth(); -} - -void draw() { - //create an alpha blended background - fill(0,1); - rect(0,0,width,height); - - //probabilities for 3 different cases (these need to add up to 100% since something always occurs here!) - float p1 = 0.05; // 5% chance of pure white occurring - float p2 = 0.80 + p1; // 80% chance of gray occuring - //float p3 = 1.0 - p2 ; // 15% chance of black (we don't actually need this line since it is - // by definit n, the "in all other cases" part of our else - float num = random(1); // pick a random number between 0 and 1 - if (num -// The Nature of Code - -// A random walker class! - -class Walker { - PVector location; - - PVector noff; - - Walker() { - location = new PVector(width/2, height/2); - noff = new PVector(random(1000),random(1000)); - } - - void display() { - strokeWeight(2); - fill(127); - stroke(0); - ellipse(location.x, location.y, 48, 48); - } - - // Randomly move up, down, left, right, or stay in one place - void walk() { - - location.x = map(noise(noff.x),0,1,0,width); - location.y = map(noise(noff.y),0,1,0,height); - - noff.add(0.01,0.01,0); - } -} - diff --git a/java/examples/Books/Nature of Code/introduction/NOC_I_5_NoiseWalk/_I_5_NoiseWalk.pde b/java/examples/Books/Nature of Code/introduction/NOC_I_5_NoiseWalk/_I_5_NoiseWalk.pde deleted file mode 100644 index e8f6a90a4..000000000 --- a/java/examples/Books/Nature of Code/introduction/NOC_I_5_NoiseWalk/_I_5_NoiseWalk.pde +++ /dev/null @@ -1,23 +0,0 @@ -// Noise Walker -// Daniel Shiffman -// The Nature of Code - -Walker w; - -void setup() { - size(800, 200); - smooth(); - frameRate(30); - - // Create a walker object - w = new Walker(); -} - -void draw() { - background(255); - // Run the walker object - w.walk(); - w.display(); -} - - diff --git a/java/examples/Books/Nature of Code/introduction/Noise1D/Noise1D.pde b/java/examples/Books/Nature of Code/introduction/Noise1D/Noise1D.pde deleted file mode 100644 index a1be010e8..000000000 --- a/java/examples/Books/Nature of Code/introduction/Noise1D/Noise1D.pde +++ /dev/null @@ -1,31 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/ - -float xoff = 0.0; -float xincrement = 0.01; - -void setup() { - size(200,200); - background(0); - smooth(); - noStroke(); -} - -void draw() { - // Create an alpha blended background - fill(0, 10); - rect(0,0,width,height); - - //float n = random(0,width); // Try this line instead of noise - - // Get a noise value based on xoff and scale it according to the window's width - float n = noise(xoff)*width; - - // With each cycle, increment xoff - xoff += xincrement; - - // Draw the ellipse at the value produced by perlin noise - fill(200); - ellipse(n,height/2,16,16); -} diff --git a/java/examples/Books/Nature of Code/introduction/Noise2D/Noise2D.pde b/java/examples/Books/Nature of Code/introduction/Noise2D/Noise2D.pde deleted file mode 100644 index dc231badc..000000000 --- a/java/examples/Books/Nature of Code/introduction/Noise2D/Noise2D.pde +++ /dev/null @@ -1,41 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/ - -float increment = 0.02; - -void setup() { - size(800,200); - noLoop(); -} - -void draw() { - background(0); - - // Optional: adjust noise detail here - // noiseDetail(8,0.65f); - - loadPixels(); - - float xoff = 0.0; // Start xoff at 0 - - // For every x,y coordinate in a 2D space, calculate a noise value and produce a brightness value - for (int x = 0; x < width; x++) { - xoff += increment; // Increment xoff - float yoff = 0.0; // For every xoff, start yoff at 0 - for (int y = 0; y < height; y++) { - yoff += increment; // Increment yoff - - // Calculate noise and scale by 255 - float bright = noise(xoff,yoff)*255; - - // Try using this line instead - //float bright = random(0,255); - - // Set each pixel onscreen to a grayscale value - pixels[x+y*width] = color(bright); - } - } - - updatePixels(); -} diff --git a/java/examples/Books/Nature of Code/introduction/NoiseDistribution/NoiseDistribution.pde b/java/examples/Books/Nature of Code/introduction/NoiseDistribution/NoiseDistribution.pde deleted file mode 100644 index 56af3a708..000000000 --- a/java/examples/Books/Nature of Code/introduction/NoiseDistribution/NoiseDistribution.pde +++ /dev/null @@ -1,33 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// Testing Distribution of Perlin Noise generated #'s vs. Randoms - -float[] vals; -float[] norms; -float xoff = 0.0f; - -void setup() { - size(300,200); - vals = new float[width]; - norms = new float[width]; -} - -void draw() { - background(100); - float n = noise(xoff); - int index = int(n*width); - vals[index]++; - xoff += 0.01; - stroke(255); - boolean normalization = false; - float maxy = 0.0; - for (int x = 0; x < vals.length; x++) { - line(x,height,x,height-norms[x]); - if (vals[x] > height) normalization = true; - if(vals[x] > maxy) maxy = vals[x]; - } - for (int x = 0; x < vals.length; x++) { - if (normalization) norms[x] = (vals[x] / maxy) * (height); - else norms[x] = vals[x]; - } -} diff --git a/java/examples/Books/Nature of Code/introduction/NoiseWalkAcceleration/NoiseWalkAcceleration.pde b/java/examples/Books/Nature of Code/introduction/NoiseWalkAcceleration/NoiseWalkAcceleration.pde deleted file mode 100644 index e762a22e2..000000000 --- a/java/examples/Books/Nature of Code/introduction/NoiseWalkAcceleration/NoiseWalkAcceleration.pde +++ /dev/null @@ -1,24 +0,0 @@ -// Noise Walker -// Daniel Shiffman -// The Nature of Code - -Walker w; - -void setup() { - size(640,360); - smooth(); - - // Create a walker object - w = new Walker(); - -} - -void draw() { - background(255); - // Run the walker object - w.walk(); - w.display(); -} - - - diff --git a/java/examples/Books/Nature of Code/introduction/NoiseWalkAcceleration/Walker.pde b/java/examples/Books/Nature of Code/introduction/NoiseWalkAcceleration/Walker.pde deleted file mode 100644 index 78190295a..000000000 --- a/java/examples/Books/Nature of Code/introduction/NoiseWalkAcceleration/Walker.pde +++ /dev/null @@ -1,65 +0,0 @@ -// Random Walker -// Daniel Shiffman -// The Nature of Code - -// A random walker class! - -class Walker { - PVector location; - PVector velocity; - PVector acceleration; - - ArrayList history; - - PVector noff; - - - Walker() { - location = new PVector(width/2, height/2); - history = new ArrayList(); - noff = new PVector(random(1000), random(1000)); - velocity = new PVector(); - acceleration = new PVector(); - } - - void display() { - stroke(0); - fill(175); - rectMode(CENTER); - rect(location.x, location.y, 16, 16); - - beginShape(); - stroke(0); - noFill(); - for (PVector v: history) { - vertex(v.x, v.y); - } - endShape(); - } - - // Randomly move up, down, left, right, or stay in one place - void walk() { - - - acceleration.x = map(noise(noff.x), 0, 1, -1, 1); - acceleration.y = map(noise(noff.y), 0, 1, -1, 1); - acceleration.mult(0.1); - - noff.add(0.01, 0.01, 0); - - velocity.add(acceleration); - velocity.limit(1); - location.add(velocity); - - - history.add(location.get()); - if (history.size() > 1000) { - history.remove(0); - } - - // Stay on the screen - location.x = constrain(location.x, 0, width-1); - location.y = constrain(location.y, 0, height-1); - } -} - diff --git a/java/examples/Books/Nature of Code/introduction/NoiseWalkVelocity/NoiseWalkVelocity.pde b/java/examples/Books/Nature of Code/introduction/NoiseWalkVelocity/NoiseWalkVelocity.pde deleted file mode 100644 index f656f8073..000000000 --- a/java/examples/Books/Nature of Code/introduction/NoiseWalkVelocity/NoiseWalkVelocity.pde +++ /dev/null @@ -1,25 +0,0 @@ -// Noise Walker -// Daniel Shiffman -// The Nature of Code - -Walker w; - -void setup() { - size(400,400); - smooth(); - frameRate(30); - - // Create a walker object - w = new Walker(); - -} - -void draw() { - background(255); - // Run the walker object - w.walk(); - w.display(); -} - - - diff --git a/java/examples/Books/Nature of Code/introduction/NoiseWalkVelocity/Walker.pde b/java/examples/Books/Nature of Code/introduction/NoiseWalkVelocity/Walker.pde deleted file mode 100644 index adcd64b17..000000000 --- a/java/examples/Books/Nature of Code/introduction/NoiseWalkVelocity/Walker.pde +++ /dev/null @@ -1,60 +0,0 @@ -// Random Walker (No Vectors) -// Daniel Shiffman -// The Nature of Code - -// A random walker class! - -class Walker { - PVector location; - PVector velocity; - - ArrayList history; - - PVector noff; - - - Walker() { - location = new PVector(width/2, height/2); - history = new ArrayList(); - noff = new PVector(random(1000), random(1000)); - velocity = new PVector(); - } - - void display() { - stroke(0); - fill(175); - rectMode(CENTER); - rect(location.x, location.y, 16, 16); - - beginShape(); - stroke(0); - noFill(); - for (PVector v: history) { - vertex(v.x, v.y); - } - endShape(); - } - - // Randomly move up, down, left, right, or stay in one place - void walk() { - - - velocity.x = map(noise(noff.x), 0, 1, -1, 1); - velocity.y = map(noise(noff.y), 0, 1, -1, 1); - velocity.mult(5); - - noff.add(0.01, 0.01, 0); - - location.add(velocity); - - history.add(location.get()); - if (history.size() > 1000) { - history.remove(0); - } - - // Stay on the screen - location.x = constrain(location.x, 0, width-1); - location.y = constrain(location.y, 0, height-1); - } -} - diff --git a/java/examples/Books/Nature of Code/introduction/RandomWalk/RandomWalk.pde b/java/examples/Books/Nature of Code/introduction/RandomWalk/RandomWalk.pde deleted file mode 100644 index 7e0c65aa6..000000000 --- a/java/examples/Books/Nature of Code/introduction/RandomWalk/RandomWalk.pde +++ /dev/null @@ -1,24 +0,0 @@ -// Random Walker (No Vectors) -// Daniel Shiffman -// The Nature of Code - -Walker w; - -void setup() { - size(400,400); - frameRate(30); - - // Create a walker object - w = new Walker(); - -} - -void draw() { - background(255); - // Run the walker object - w.walk(); - w.render(); -} - - - diff --git a/java/examples/Books/Nature of Code/introduction/RandomWalk/Walker.pde b/java/examples/Books/Nature of Code/introduction/RandomWalk/Walker.pde deleted file mode 100644 index b0d26d6b1..000000000 --- a/java/examples/Books/Nature of Code/introduction/RandomWalk/Walker.pde +++ /dev/null @@ -1,34 +0,0 @@ -// Random Walker (No Vectors) -// Daniel Shiffman -// The Nature of Code - -// A random walker class! - -class Walker { - float x, y; - - Walker() { - x = width/2; - y = height/2; - } - - void render() { - stroke(0); - fill(175); - rectMode(CENTER); - rect(x, y, 40, 40); - } - - // Randomly move up, down, left, right, or stay in one place - void walk() { - float vx = random(-2, 2); - float vy = random(-2, 2); - x += vx; - y += vy; - - // Stay on the screen - x = constrain(x, 0, width-1); - y = constrain(y, 0, height-1); - } -} - diff --git a/java/examples/Books/Nature of Code/introduction/RandomWalkLevy/RandomWalkLevy.pde b/java/examples/Books/Nature of Code/introduction/RandomWalkLevy/RandomWalkLevy.pde deleted file mode 100644 index 6c9507216..000000000 --- a/java/examples/Books/Nature of Code/introduction/RandomWalkLevy/RandomWalkLevy.pde +++ /dev/null @@ -1,20 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/ - -Walker w; - -void setup() { - size(640,480); - // Create a walker object - w = new Walker(); - background(0); -} - -void draw() { - // Run the walker object - w.step(); - w.render(); -} - - diff --git a/java/examples/Books/Nature of Code/introduction/RandomWalkLevy/Walker.pde b/java/examples/Books/Nature of Code/introduction/RandomWalkLevy/Walker.pde deleted file mode 100644 index 147040bbe..000000000 --- a/java/examples/Books/Nature of Code/introduction/RandomWalkLevy/Walker.pde +++ /dev/null @@ -1,54 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/ - -// A random walker object! - -class Walker { - float x, y; - - float prevX, prevY; - - Walker() { - x = width/2; - y = height/2; - } - - void render() { - stroke(255); - line(prevX,prevY,x, y); - } - - // Randomly move according to floating point values - void step() { - prevX = x; - prevY = y; - - float stepx = random(-1, 1); - float stepy = random(-1, 1); - - float stepsize = montecarlo()*50; - stepx *= stepsize; - stepy *= stepsize; - - x += stepx; - y += stepy; - x = constrain(x, 0, width-1); - y = constrain(y, 0, height-1); - } -} - - -float montecarlo() { - while (true) { - - float r1 = random(1); - float probability = pow(1.0 - r1,8); - - float r2 = random(1); - if (r2 < probability) { - return r1; - } - } -} - diff --git a/java/examples/Books/Nature of Code/introduction/RandomWalkNoise/RandomWalkNoise.pde b/java/examples/Books/Nature of Code/introduction/RandomWalkNoise/RandomWalkNoise.pde deleted file mode 100644 index 7b85201cb..000000000 --- a/java/examples/Books/Nature of Code/introduction/RandomWalkNoise/RandomWalkNoise.pde +++ /dev/null @@ -1,20 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/ - -Walker w; - -void setup() { - size(640,360); - smooth(); - w = new Walker(); - background(0); -} - -void draw() { - // Run the walker object - w.step(); - w.render(); -} - - diff --git a/java/examples/Books/Nature of Code/introduction/RandomWalkNoise/Walker.pde b/java/examples/Books/Nature of Code/introduction/RandomWalkNoise/Walker.pde deleted file mode 100644 index 4bf77fbdd..000000000 --- a/java/examples/Books/Nature of Code/introduction/RandomWalkNoise/Walker.pde +++ /dev/null @@ -1,39 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/ - -// A random walker object! - -class Walker { - float x, y; - float tx, ty; - - float prevX, prevY; - - Walker() { - tx = 0; - ty = 10000; - x = map(noise(tx), 0, 1, 0, width); - y = map(noise(ty), 0, 1, 0, height); - } - - void render() { - stroke(255); - line(prevX, prevY, x, y); - } - - // Randomly move according to floating point values - void step() { - - prevX = x; - prevY = y; - - x = map(noise(tx), 0, 1, 0, width); - y = map(noise(ty), 0, 1, 0, height); - - tx += 0.01; - ty += 0.01; - - } -} - diff --git a/java/examples/Books/Nature of Code/introduction/RandomWalkPVector/RandomWalkPVector.pde b/java/examples/Books/Nature of Code/introduction/RandomWalkPVector/RandomWalkPVector.pde deleted file mode 100644 index 7e0c65aa6..000000000 --- a/java/examples/Books/Nature of Code/introduction/RandomWalkPVector/RandomWalkPVector.pde +++ /dev/null @@ -1,24 +0,0 @@ -// Random Walker (No Vectors) -// Daniel Shiffman -// The Nature of Code - -Walker w; - -void setup() { - size(400,400); - frameRate(30); - - // Create a walker object - w = new Walker(); - -} - -void draw() { - background(255); - // Run the walker object - w.walk(); - w.render(); -} - - - diff --git a/java/examples/Books/Nature of Code/introduction/RandomWalkPVector/Walker.pde b/java/examples/Books/Nature of Code/introduction/RandomWalkPVector/Walker.pde deleted file mode 100644 index 161db0a23..000000000 --- a/java/examples/Books/Nature of Code/introduction/RandomWalkPVector/Walker.pde +++ /dev/null @@ -1,30 +0,0 @@ -// Random Walker (No Vectors) -// Daniel Shiffman -// The Nature of Code -// A random walker class! - -class Walker { - PVector loc; - - Walker() { - loc = new PVector(width/2,height/2); - } - - void render() { - stroke(0); - fill(175); - rectMode(CENTER); - rect(loc.x,loc.y,40,40); - } - - // Randomly move up, down, left, right, or stay in one place - void walk() { - PVector vel = new PVector(random(-2,2),random(-2,2)); - loc.add(vel); - - // Stay on the screen - loc.x = constrain(loc.x,0,width-1); - loc.y = constrain(loc.y,0,height-1); - } -} - diff --git a/java/examples/Books/Nature of Code/introduction/RandomWalkTraditional2/RandomWalkTraditional2.pde b/java/examples/Books/Nature of Code/introduction/RandomWalkTraditional2/RandomWalkTraditional2.pde deleted file mode 100644 index d45577c28..000000000 --- a/java/examples/Books/Nature of Code/introduction/RandomWalkTraditional2/RandomWalkTraditional2.pde +++ /dev/null @@ -1,20 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/ - -Walker w; - -void setup() { - size(200,200); - // Create a walker object - w = new Walker(); - background(0); -} - -void draw() { - // Run the walker object - w.step(); - w.render(); -} - - diff --git a/java/examples/Books/Nature of Code/introduction/RandomWalkTraditional2/Walker.pde b/java/examples/Books/Nature of Code/introduction/RandomWalkTraditional2/Walker.pde deleted file mode 100644 index a73abfb93..000000000 --- a/java/examples/Books/Nature of Code/introduction/RandomWalkTraditional2/Walker.pde +++ /dev/null @@ -1,29 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/ - -// A random walker object! - -class Walker { - int x,y; - - Walker() { - x = width/2; - y = height/2; - } - - void render() { - stroke(255); - point(x,y); - } - - // Randomly move to any neighboring pixel (or stay in the same spot) - void step() { - int stepx = int(random(3))-1; - int stepy = int(random(3))-1; - x += stepx; - y += stepy; - x = constrain(x,0,width-1); - y = constrain(y,0,height-1); - } -} diff --git a/java/examples/Books/Nature of Code/introduction/RandomWalkTraditional3/RandomWalkTraditional3.pde b/java/examples/Books/Nature of Code/introduction/RandomWalkTraditional3/RandomWalkTraditional3.pde deleted file mode 100644 index d45577c28..000000000 --- a/java/examples/Books/Nature of Code/introduction/RandomWalkTraditional3/RandomWalkTraditional3.pde +++ /dev/null @@ -1,20 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/ - -Walker w; - -void setup() { - size(200,200); - // Create a walker object - w = new Walker(); - background(0); -} - -void draw() { - // Run the walker object - w.step(); - w.render(); -} - - diff --git a/java/examples/Books/Nature of Code/introduction/RandomWalkTraditional3/Walker.pde b/java/examples/Books/Nature of Code/introduction/RandomWalkTraditional3/Walker.pde deleted file mode 100644 index a3991d367..000000000 --- a/java/examples/Books/Nature of Code/introduction/RandomWalkTraditional3/Walker.pde +++ /dev/null @@ -1,30 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/ - -// A random walker object! - -class Walker { - float x, y; - - Walker() { - x = width/2; - y = height/2; - } - - void render() { - stroke(255); - point(x, y); - } - - // Randomly move according to floating point values - void step() { - float stepx = random(-1, 1); - float stepy = random(-1, 1); - x += stepx; - y += stepy; - x = constrain(x, 0, width-1); - y = constrain(y, 0, height-1); - } -} - diff --git a/java/examples/Books/Nature of Code/introduction/RandomWalkTrail/RandomWalkTrail.pde b/java/examples/Books/Nature of Code/introduction/RandomWalkTrail/RandomWalkTrail.pde deleted file mode 100644 index 829dd5a6a..000000000 --- a/java/examples/Books/Nature of Code/introduction/RandomWalkTrail/RandomWalkTrail.pde +++ /dev/null @@ -1,24 +0,0 @@ -// Random Walker (No Vectors) -// Daniel Shiffman -// The Nature of Code - -Walker w; - -void setup() { - size(400,400); - frameRate(30); - - // Create a walker object - w = new Walker(); - -} - -void draw() { - background(255); - // Run the walker object - w.walk(); - w.display(); -} - - - diff --git a/java/examples/Books/Nature of Code/introduction/RandomWalkTrail/Walker.pde b/java/examples/Books/Nature of Code/introduction/RandomWalkTrail/Walker.pde deleted file mode 100644 index 4fbab1eb1..000000000 --- a/java/examples/Books/Nature of Code/introduction/RandomWalkTrail/Walker.pde +++ /dev/null @@ -1,49 +0,0 @@ -// Random Walker (No Vectors) -// Daniel Shiffman -// The Nature of Code - -// A random walker class! - -class Walker { - PVector location; - - ArrayList history; - - - Walker() { - location = new PVector(width/2, height/2); - history = new ArrayList(); - } - - void display() { - stroke(0); - fill(175); - rectMode(CENTER); - rect(location.x, location.y, 16, 16); - - beginShape(); - stroke(0); - noFill(); - for (PVector v: history) { - vertex(v.x, v.y); - } - endShape(); - } - - // Randomly move up, down, left, right, or stay in one place - void walk() { - PVector vel = new PVector(random(-2, 2), random(-2, 2)); - location.add(vel); - - // Stay on the screen - location.x = constrain(location.x, 0, width-1); - location.y = constrain(location.y, 0, height-1); - - - history.add(location.get()); - if (history.size() > 1000) { - history.remove(0); - } - } -} - diff --git a/java/examples/Books/Nature of Code/introduction/SimpleProbablility/SimpleProbablility.pde b/java/examples/Books/Nature of Code/introduction/SimpleProbablility/SimpleProbablility.pde deleted file mode 100644 index 8843f1581..000000000 --- a/java/examples/Books/Nature of Code/introduction/SimpleProbablility/SimpleProbablility.pde +++ /dev/null @@ -1,34 +0,0 @@ -// Daniel Shiffman -// The Nature of Code -// http://www.shiffman.net/ - -int x,y; - -void setup() { - size(200,200); - background(0); - smooth(); -} - -void draw() { - //create an alpha blended background - fill(0,1); - rect(0,0,width,height); - - //calculate a probability between 0 and 100% based on mouseX location - float prob = (mouseX / (float) width); - - //get a random floating point value between 0 and 1 - float r = random(1); - - //test the random value against the probability and trigger an event - if (r < prob) { - noStroke(); - fill(255); - ellipse(x,y,10,10); - } - - // X and Y walk through a grid - x = (x + 10) % width; - if (x == 0) y = (y + 10) % width; -}